我在Matlab脚本中有复杂的代码块,它们作用于大型非稀疏数组.该代码对数组中的随机元素以及读取操作执行许多写操作.相同的代码必须针对不同的(大)数组执行(即,相同的代码块,不同的数组变量名称除外).
我不想要只有数组名称不同的长重复代码块.
不幸的是,当我创建一个函数来执行操作时,所以代码块只出现一次,性能会降低10倍或更多(可能是由于复制了数组).但是,我不需要复制数组.我宁愿"通过引用传递",因此函数调用的目的只是为了避免重复的代码块.但是,似乎没有办法避免写时复制语义.
此外,我不可能(据我所知)创建一个脚本(而不是函数)来实现这一点,因为脚本必须包含与调用脚本相同的变量名称,因此我需要为每个数组使用不同的脚本我希望运行脚本,它什么也得不到(我仍然会有重复的代码块).
我已经考虑创建一个别名变量名称来"替换"感兴趣的数组变量名称,在这种情况下,我可以调用脚本并避免重复的代码.但是,我找不到任何在Matlab中创建别名的方法.
最后,我尝试编写一个利用该evalin()函数的函数,并将数组变量的字符串名称传递给此函数,但是虽然这有效,但性能也要慢得多 - 与将值按值传递给函数大致相同(性能至少下降10倍).
我得出的结论是,在Matlab中,在非稀疏数组上执行复杂操作时,避免重复代码块是不可能的,以避免Matlab似乎使用避免重复代码块的任何可能技术所带来的可怕开销.
我觉得很难相信,但我无法找到解决办法.
有没有人知道在Matlab中对多个非稀疏数组执行相同的复杂操作时避免重复代码块的方法?
正如Loren在他的博客中指出的那样,MATLAB确实支持矩阵的在线操作,主要包括通过引用传递数组,在函数中修改它们以及返回结果.您似乎知道这一点,但您错误地声明,因为脚本必须包含与调用脚本相同的变量名称.这是代码示例,显示这是错误的.测试时,请逐字复制并保存为功能:
function inplace_test
y = zeros(1,1e8);
x = zeros(1,1e8);
tic; x = compute(x); toc
tic; y = compute(y); toc
tic; x = computeIP(x); toc
tic; y = computeIP(y); toc
tic; x = x+1; toc
end
function x=computeIP(x)
x = x+1;
end
function y=compute(x)
y = x+1;
end
Run Code Online (Sandbox Code Playgroud)
我的电脑上的时间结果:
Elapsed time is 0.243335 seconds.
Elapsed time is 0.251495 seconds.
Elapsed time is 0.090949 seconds.
Elapsed time is 0.088894 seconds.
Elapsed time is 0.090638 seconds.
Run Code Online (Sandbox Code Playgroud)
如您所见,对于两个输入数组和使用就地函数的最后两个调用同样快.而且,它们与没有功能的运行同样快.唯一重要的是函数输入和输出参数内部是相同的.还有一件事......xyx = x+1
如果我猜测你的代码有什么问题,我会说你做了嵌入式函数,你希望它们就位.他们不是.所以下面的代码不起作用:
function inplace_test
y = zeros(1,1e8);
x = zeros(1,1e8);
tic; x = compute(x); toc
tic; y = compute(y); toc
tic; x = computeIP(x); toc
tic; y = computeIP(y); toc
tic; x = x+1; toc
function x=computeIP(x)
x = x+1;
end
function y=compute(x)
y = x+1;
end
end
Elapsed time is 0.247798 seconds.
Elapsed time is 0.257521 seconds.
Elapsed time is 0.229774 seconds.
Elapsed time is 0.237215 seconds.
Elapsed time is 0.090446 seconds.
Run Code Online (Sandbox Code Playgroud)
底线 - 小心那些嵌套函数..