我不确定您是如何得出循环代码比矢量化代码慢的结论,但这里有一个基准和一些结果背景!
我使用的是 2015b,所以这可能会利用 Matlab 的new(ish) JIT compiler。
function benchie()
A = rand(1e9, 1);
b = 0.01;
f = @() original(A,b);
g = @() usingloop(A,b);
disp(['Original with logical A <= b: ', num2str(timeit(f)), ' sec']);
disp(['Looping until found, then break: ', num2str(timeit(g)), ' sec']);
end
% Both of these functions return the same value for idx
function idx = original(A,b)
idx = find(A <= b, 1);
end
function idx = usingloop(A,b)
for idx = 1:length(A)
if A(idx) <= b
break
end
end
end
输出:
Original with logical A <= b: 0.83666 sec
Warning: The measured time for F [function g] may be inaccurate because it is running
too fast. Try measuring something that takes longer.
> In timeit (line 158)
In benchie (line 7)
Looping until found, then break: 1.8043e-06 sec
总结:
使A 与我的RAM 允许的大小(8GB)一样大,usingloop 方法仍然太快,timeit 无法认为自己准确!这两个函数都给出了相同的答案,我认为usingloop 要快几个数量级。
我很想包含一个图表,显示不同大小数组的时间比较,但不能因为usingloop 太快...
注意:我使用idx 作为我的变量,而不是i。这是因为默认情况下i 是复数常量sqrt(-1),并且在重写时,您将立即招致(小)性能损失!
编辑:
我运行了另一个测试,A = 1e8:-1:1; 和 b 在通过 A 的十分之一的值处查看向量化的开销何时超过了进一步循环到数组中所需的时间。下面是输出:
您可以看到逻辑比较的开销几乎是所有时间所需的,并且无论位置如何,该向量的实际索引都非常小。相比之下,一旦所需元素进入数组的路径很短,循环方法就很糟糕。
鉴于 MATLAB 在使用矢量化和逻辑索引进行快速计算方面享有盛誉,我将回应 @beaker 的评论,即自定义(编译的)C 函数可能是查看原始方法改进的唯一方法。