一个简单的问题,但我只是为了确保我没有忽略一个明显的解决方案,它可以更有效。
如果一个人有很大的数据缓冲区,比如说非常大的列表,需要更新,并且想将它传递给一个函数以在函数内部进行更新,如
a = Table[0,{10}]
a = update[a]
并且由于我不能使用按引用传递(在 CDF 中,不能将函数的属性更改为任何东西,例如 HoldFirst),所以我被迫在函数本身内按顺序制作列表的副本更新它,并返回副本。
我的问题是,除了使用不好的“全局变量”之外,还有更有效的方法吗?
附言。大约一年前,我通过引用询问了副本,这是 我的 Mathgroup 问题的链接。(顺便说一句,感谢 Leonid 的回答,这是有用的答案)。
但是我在这里的问题有点不同,因为现在我不能使用 HoldFirst,是否还有其他我没有看到的替代方法来避免这种额外的数据复制,当大小变得太大时,它似乎会减慢程序的速度大的。
(不能使用 SetAttributes 及其朋友,CDF 中不允许)。
我将首先展示基本示例,然后展示如果我可以使用 HoldFirst,我会怎么做。
例子
update[a_List] := Module[{copyOfa = a}, copyOfa[[1]] = 5; copyOfa]
a = Table[0, {10}];
a = update[a]
----> {5, 0, 0, 0, 0, 0, 0, 0, 0, 0}
如果我可以使用 HoldFirst,我会写
update[a_] := Module[{}, a[[1]] = 5; a]
Attributes[update] = {HoldFirst};
a = Table[0, {10}];
a = update[a]
----> {5, 0, 0, 0, 0, 0, 0, 0, 0, 0}
效率更高,因为没有复制。通过参考。
我可以使用全局变量,如
a = Table[0, {10}];
updateMya[] := Module[{}, a[[1]] = 5]
updateMya[];
a
----> {5, 0, 0, 0, 0, 0, 0, 0, 0, 0}
但这当然是糟糕的编程,即使它非常快。
由于我有大型数据缓冲区,并且我想模块化我的 Mathematica 代码,我需要创建将大数据传递给它以进行处理的函数,但同时又想保持它“高效”。
可以看到任何其他选项来做到这一点?
抱歉,如果之前在这里问过这个问题,很难搜索到。
谢谢,
加法1
使用 Unevaluated 很容易使用,但我不再能够使用我必须确保列表正在传递的类型检查。例如
update[a_List] := Module[{}, a[[1]] = 5; a]
a = Table[0, {10}];
a = update[Unevaluated[a]]
现在调用不会“绑定”到定义,因为“a”现在没有标题列表。
因此,我失去了代码中的一些稳健性。但是在 CDF 中使用 Unevaluated 确实有效,并且更改代码以使用它很容易。我只需要删除我在那里的那些额外的“类型检查”以使其工作。