我在函数内部的循环中有一个函数。 内部函数在内存中获取并存储大量数据(作为全局变量......我使用“R”,类似于“S-Plus”)。 循环遍历要获取的长数据列表。 外部函数启动该过程并传入要获取的数据集列表。

for (dataset in list_of_datasets) {
  for (datachunk in dataset) {
    <process datachunk>
    <store result? as vector? where?>
  }
}

我编写了内部函数来存储每个数据集,然后移动到下一个数据集,因此外部函数的所有工作都作为全局变量的副作用发生...一个大禁忌。 这比收集和返回一个巨大的,占用记忆的向量矢量更好还是更糟? 是否有优越的第三种方法?

如果我将数据向量存储在数据库而不是内存中,答案会改变吗? 理想情况下,我希望能够终止该功能(或由于网络超时而使其失败),而不会丢失在终止之前处理的所有信息。

===============>>#1 票数:9

在外部函数中使用变量而不是全局变量。 这将为您提供两种方法中的最佳方法:您不会改变全局状态,也不会复制大量数据。 如果您必须提前退出,只需返回部分结果。

(参见R手册中的“范围”部分: http//cran.r-project.org/doc/manuals/R-intro.html#Scope

===============>>#2 票数:6

记住你的Knuth。 “过早的优化是所有编程邪恶的根源。”

试试副作用免费版。 看它是否符合您的性能目标。 如果确实如此,那么首先你没有问题; 如果没有,那么使用副作用,并为下一个程序员注意你的手被强迫。

===============>>#3 票数:4

它不会对内存使用产生太大影响,所以你不妨使代码干净。

由于R具有对变量的复制修改,因此修改全局对象将具有与在返回值中传递某些内容相同的内存含义。

如果将输出存储在数据库中(甚至存储在文件中),则不会出现内存使用问题,并且数据将在创建时逐步可用,而不是仅在最后。 数据库的速度是否更快主要取决于您使用的内存量:减少是垃圾收集来支付写入磁盘的成本。

R中有时间和内存分析器,因此您可以凭经验查看影响。

===============>>#4 票数:1

我不确定我理解这个问题,但我有几个解决方案。

  1. 在函数内部,创建一个向量列表并返回它。

  2. 在函数内部,创建一个环境并存储其中的所有向量。 只要确保在发生错误时返回环境。

在R:

help(environment)

# You might do something like this:

outer <- function(datasets) {
  # create the return environment
  ret.env <- new.env()
  for(set in dataset) {
    tmp <- inner(set)
    # check for errors however you like here.  You might have inner return a list, and
    # have the list contain an error component
    assign(set, tmp, envir=ret.env)
  }
  return(ret.env)
}

#The inner function might be defined like this

inner <- function(dataset) {
  # I don't know what you are doing here, but lets pretend you are reading a data file
  # that is named by dataset
  filedata <- read.table(dataset, header=T)
  return(filedata)
}

雷夫

===============>>#5 票数:1

仅供参考,这是一个完整的样本玩具解决方案,可以避免副作用:

outerfunc <- function(names) {
  templist <- list()
  for (aname in names) {
    templist[[aname]] <- innerfunc(aname)
  }
  templist
}

innerfunc <- function(aname) {
  retval <- NULL
  if ("one" %in% aname) retval <- c(1)
  if ("two" %in% aname) retval <- c(1,2)
  if ("three" %in% aname) retval <- c(1,2,3)
  retval
}

names <- c("one","two","three")

name_vals <- outerfunc(names)

for (name in names) assign(name, name_vals[[name]])

===============>>#6 票数:0

第三种方法:内部函数返回对大数组的引用,然后循环中的下一个语句取消引用并存储在需要的任何地方(理想情况下使用单个指针存储而不必记忆整个数组)。

这消除了副作用和大数据结构的传递。

===============>>#7 票数:-1

如果不知道使用的语言/编译器,很难肯定地说。 但是,如果您只是将指针/引用传递给您正在创建的对象,那么对象本身的大小与函数调用的速度无关。 在未来操纵这些数据可能是另一回事。

  ask by translate from so

未解决问题?本站智能推荐:

1回复

使用常量全局变量可以完全消除“副作用”的问题吗?

我知道函数式编程(FP)的目的是禁止“副作用”,传统上,由于使用了全局变量,这种副作用通常在面向对象的命令式语言中出现。 但是,在OOP(非FP)语言中,如果使用恒定的全局变量(因此其值永远不会改变),“副作用”会消失吗?
1回复

R中的作用域分配以及局部,绑定和全局变量

我是R的新手,试图弄清楚局部,绑定和全局变量的行为。 我对以下问题感到困惑。 如果我以以下方式编写函数,那么函数f的局部变量,边界变量和全局变量是什么?
1回复

在R中传递大对象的内存有效方法

我有一个函数需要访问其父环境中的变量(调用该函数的范围)。 变量在内存方面很大,所以我不希望将值传递给被调用的函数。 除了在全局范围内声明变量之外,还有一种标准的方法吗? 例如: 我想访问y in g() 。 所以像这样: 这可能吗? 谢谢
1回复

R中功能内的功能不起作用

我定义了以下功能: 当我尝试通过以下方式运行第二个功能时: 那么它无法识别second_table并给我以下错误: 我想这是关于环境的问题,但我不明白这一点。 非常感谢您的帮助。
2回复

是否可以向函数传递用于创建全局矩阵的字符串?

我正在使用基本SIR模型作为动机的生物入门课程中教授R编程。 在学生获得基本模型后,我希望他们改变参数以查看其如何改变感染动态。 下面的代码有效,但是每次运行都返回相同的名为“ dmatrix”: 我想添加选项以传递'runSIR'一个用于创建输出矩阵的字符串,如下所示: 我
1回复

使用传递给闪亮应用程序的参数将R Shiny应用程序另存为函数

我正在构建一个具有启动闪亮应用程序功能的R包。 我希望该函数包含要传递给应用程序的参数。 我发现工作的唯一方法是设置全局值,然后让应用使用该全局值: 有没有更好的方法来传递我的“ MonteCarlo”参数以在整个闪亮的应用程序中使用? 请注意,我试图避免仅将“ MonteCarl
2回复

<<-不起作用-R-从外部函数调用对象[关闭]

我浏览了这里的论坛,并发现<<-将函数内的变量分配给全局变量(可在函数外访问)。 我在下面这样做,但无济于事-有什么想法吗? 对象billdata是我在Billeddata_import()清理的数据表,希望在以后的函数中使用它。 单独运行该函数将产生:
3回复

Scala中的“副作用词汇闭包”与功能

在他的回答评论部分 ,Apocalisp陈述如下: 好吧,你确实要求一个功能。 一个侧面有效的[原文如此]词汇封闭显然不是一个功能。 “副作用词汇封闭”究竟是什么意思,它与功能有什么不同? 我的猜测是,他们试图在函数式编程意义上区分函数 - 不允许任何副作用(例如改变变
1回复

输入特征以检测可调用对象是否有副作用?

我的问题很简单,但我想很难回答。 在C ++ 14中,有没有一种方法可以测试可调用对象(函数,函数成员,lambda函数,std :: function等...)是否具有副作用? 如果是这样,一个类型的特征如何: 会怎么样? 我对可以返回假阳性的特征(比如说一个函数没有
2回复

有没有办法确定JavaScript函数是否有副作用? [关闭]

给定Javascript函数,是否可以验证函数没有副作用; 即,该函数不会更改在函数范围之外声明的任何变量的值?