matlab中的c=complex(a,b)
比做c=a+1i*b
慢得多。
以下是Matlab 2018a
a=rand(15000);
b=rand(15000);
%
clear c;
tic; c=a+1i*b; toc
Elapsed time is 0.338525 seconds
%
clear c;
tic; c=complex(a,b); toc
Elapsed time is 2.542403 seconds.
complex
在任何情况下实际上都有用吗?为什么这么慢?
documentation和命令行帮助提供了一些关于何时可能有用的提示:当你想强制复杂类型的结果时,即使虚部为零,或者你有整数数据类型作为输入:
C = COMPLEX(A,B)
返回复杂的结果A + Bi
如果
B
全为零,则C
复杂,所有零虚部,与A+0i
的加法结果不同,complex
返回严格实际结果。当
A+1i*B
和A+1j*B
不是单个或双重,或者当A
全为零时,B
函数为B
或complex
等表达式提供了有用的替代。
至于它为什么慢?我们只能猜测,因为它是一个内置函数;但是检查输入是否不是浮点数,或者如果第二个输入全部为零,则可能会占用一些额外的时间。
我想补充一些历史观点:
在R2018a之前的MATLAB版本中,复数在内部存储在单独的实数和虚数数组中。因此,complex(a,b)
的结果可能只指向两个输入数组的数据。因此,与a+1i*b
相比,complex
非常快且内存效率高,而timeit
实际上需要进行算术运算并创建新的内存存储。
在当前版本的MATLAB中,复杂数据以“交错格式”存储,这意味着它是一个单独的数组,每个数组元素的实数和复数值彼此相邻。这意味着需要使用任一格式复制数据,function [t] = bench()
A = rand(10000);
B = rand(10000);
% functions to compare
fcns = {
@() compare1(A,B);
@() compare2(A,B);
};
% timeit
t = zeros(2,1);
for ii = 1:10
t = t + cellfun(@timeit, fcns);
end
end
function c = compare1(a,b)
c = a + 1i*b;
end
function c = compare2(a,b)
c = complex(a,b);
end
已失去其价值。
为什么这么慢?
事实并非如此。但是您的“基准代码”并不合适,因为它可能会在每次运行或更改顺序时表现不同。
8.0663 % a + 1i*b
8.3191 % complex(a,b)
函数是基准测试的专用函数。
complex
十次运行导致:
Luis Mendo's answer
如你所见,没有太大区别。有一个,可以解释Luis Mendo提到的[1,2,3]+1i*[1;2;3]
(类型检查,强制转换)的函数开销。
除了bsxfun(@(x,y) x+1i*y, [1,2,3], [1;2;3])
之外还有一些原因,为什么这个函数可能存在:
bsxfun(@complex, [1,2,3], [1;2;3])
相同的complex
,但是这个a+1i*b
可能比第二个选项更快(同样适用于cellfun和arrayfun,尽管我无法测试它。)