MATLAB:创建一个关闭大变量的快速函数

时间:2013-11-19 23:16:21

标签: matlab memory-management closures

我正在尝试创建一个函数,每次调用函数时都会存储一个非常大的变量。我有一个函数myfun(x,y),其中y非常大,因此执行起来很慢,因为MATLAB是按值传递的。但是,我只在程序执行期间传递变量y一次,创建一个闭包,然后传递给另一个函数重复调用:

Y = create_big_matrix();
newfun = @(x) myfun(x,Y);
some_other_fun(newfun); % This calls newfun several times

我假设每次调用newfun时,都会将Y的存储值复制到myfun。这看起来非常低效。有没有更好的方法来实现newfun,以便Y只在创建newfun时(也可能在传递给some_other_fun时)复制一次?

2 个答案:

答案 0 :(得分:1)

MATLAB has copy-on-write mechanisms会在Y被调用时阻止myfun(x,Y)的副本,除非它修改输入。在这种情况下,我认为您不必担心性能问题,但我必须查看myfun的代码并运行测试以进行验证。

引用this post on a MathWorks blog

  

有些用户认为,因为MATLAB的行为就好像数据是按值传递的(而不是通过引用传递),所以MATLAB在调用函数时总是复制输入。这不一定是真的。

本文接着描述了MATLAB识别函数修改变量的能力有限,并尽可能避免复制。另请参阅this SO answer,在写时复制as described in an old newsreader post期间总结“幕后”操作。

要调查是否正在进行复制,请使用format debug检查调用函数中pr的数据指针地址Y,并再次检查myfun内的数据指针地址{{1}}。如果是相同的,则不会发生任何副本。设置断点以逐步执行并检查此指针。

答案 1 :(得分:0)

由于Y不是函数句柄的参数,因此它只传递给函数句柄一次,即在执行时 - 包括可能存在的所有花哨的写时复制优化。 所以function_handle在定义时就得到了自己的Y版本。 执行期间,function_handle Y根本没有传递给function_handle。 您可以通过一个简单的示例来形象化:

>> r = rand();
% at this point the function_handle gets lazy copy of r, stored in its own workspace
>> f = @() r; 
>> r
r =
    0.6423
% what happens to the original r, doesn't matter to the function-handle:
>> clear r
>> f()
ans =
    0.6423

只有在原始Y被修改/删除的情况下才能进行实际复制(在删除时真正复制的可能是另一个问题)。

您可以使用Y检查functions是否真的被复制到function_handle工作区,上面的示例(r只有不同的值):

r =

Structure address = c601538 
m = 1
n = 1
pr = 4c834a60 
pi = 0
    0.4464
>> fcn = functions(f);
>> fcn.workspace{1}.r
ans =

Structure address = c6010c0 
m = 1
n = 1
pr = 4c834a60 
pi = 0
    0.4464

你可以看到,正如chappjc的回答中所讨论的那样,这个参数目前只是懒得复制 - 所以没有创建完整的副本。