首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与bsxfun相比,隐式扩展快多少?

与bsxfun相比,隐式扩展快多少?
EN

Stack Overflow用户
提问于 2017-03-02 23:50:07
回答 1查看 618关注 0票数 25

正如Steve Eddins提出的commented一样,对于小的数组,implicit expansion (在Matlab R2016b中引入)比bsxfun更快,而对于大的数组,它的速度与bsxfun相似:

在R2016b中,隐式扩展在大多数情况下与bsxfun一样快,甚至更快。隐式扩展的最佳性能增益是使用较小的矩阵和数组大小。对于较大的矩阵大小,隐式扩展的速度往往与bsxfun大致相同。

此外,发生扩展的维度可能会产生影响:

当第一维中存在扩展时,运算符可能没有bsxfun那么快。

(感谢@Poelie@rayryeng让我对此进行know about!)

自然会出现两个问题:

bsxfun

  • For相比,隐式扩展的速度快了多少? significant?

的区别是数组大小或形状是什么

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-02 23:50:07

为了测量速度的差异,已经进行了一些测试。测试考虑两种不同的操作

  • addition
  • power

和要操作的数组的四种不同形状的:

  • N×N阵列的array
  • N×N×N×N阵列带N×1×N array
  • N×N×N×N阵列的1×N阵列带1×N×N阵列

对于运算和数组形状的八种组合中的每一种,都使用隐式扩展和bsxfun进行相同的运算。使用了 N的几个值,以涵盖从小到大的数组。timeit用于可靠的计时。

本答案末尾给出了基准测试代码。它已经在R2016b,Windows10上运行,内存为12 GB。

结果

下图显示了结果。水平轴是输出数组的元素数,这是比N更好的大小度量。

还使用逻辑运算(而不是算术运算)进行了测试。为了简洁起见,这里没有显示结果,但显示了类似的趋势。

结论

根据图表:

  • 结果证实,隐式扩展对于小数组来说更快,并且对于第一维或沿着其他维度的大arrays.
  • Expanding,其速度与bsxfun相似,似乎没有太大的影响,至少在所考虑的情况下是这样。
  • 对于小数组,差异可以是十倍或更多。但是,请注意,timeit对于小尺寸并不准确,因为代码太快(实际上,它会对这种小尺寸发出警告)。
  • 当输出的元素数达到1e5左右时,两种速度变得相等。此值可以为system-dependent.

基准测试代码

代码语言:javascript
运行
复制
clear

% NxN, Nx1, addition / power
N1 = 2.^(4:1:12);
t1_bsxfun_add = NaN(size(N1));
t1_implicit_add = NaN(size(N1));
t1_bsxfun_pow = NaN(size(N1));
t1_implicit_pow = NaN(size(N1));
for k = 1:numel(N1)
    N = N1(k);
    x = randn(N,N);
    y = randn(N,1);
    % y = randn(1,N); % use this line or the preceding one
    t1_bsxfun_add(k) = timeit(@() bsxfun(@plus, x, y));
    t1_implicit_add(k) = timeit(@() x+y);
    t1_bsxfun_pow(k) = timeit(@() bsxfun(@power, x, y));
    t1_implicit_pow(k) = timeit(@() x.^y);
end

% NxNxNxN, Nx1xN, addition / power
N2 = round(sqrt(N1));
t2_bsxfun_add = NaN(size(N2));
t2_implicit_add = NaN(size(N2));
t2_bsxfun_pow = NaN(size(N2));
t2_implicit_pow = NaN(size(N2));
for k = 1:numel(N1)
    N = N2(k);
    x = randn(N,N,N,N);
    y = randn(N,1,N);
    % y = randn(1,N,N); % use this line or the preceding one
    t2_bsxfun_add(k) = timeit(@() bsxfun(@plus, x, y));
    t2_implicit_add(k) = timeit(@() x+y);
    t2_bsxfun_pow(k) = timeit(@() bsxfun(@power, x, y));
    t2_implicit_pow(k) = timeit(@() x.^y);
end

% Plots
figure
colors = get(gca,'ColorOrder');

subplot(121)
title('N\times{}N,   N\times{}1')
% title('N\times{}N,   1\times{}N') % this or the preceding
set(gca,'XScale', 'log', 'YScale', 'log')
hold on
grid on
loglog(N1.^2, t1_bsxfun_add, 's-', 'color', colors(1,:))
loglog(N1.^2, t1_implicit_add, 's-', 'color', colors(2,:))
loglog(N1.^2, t1_bsxfun_pow, '^-', 'color', colors(1,:))
loglog(N1.^2, t1_implicit_pow, '^-', 'color', colors(2,:))
legend('Addition, bsxfun', 'Addition, implicit', 'Power, bsxfun', 'Power, implicit')

subplot(122)
title('N\times{}N\times{}N{}\times{}N,   N\times{}1\times{}N')
% title('N\times{}N\times{}N{}\times{}N,   1\times{}N\times{}N') % this or the preceding
set(gca,'XScale', 'log', 'YScale', 'log')
hold on
grid on
loglog(N2.^4, t2_bsxfun_add, 's-', 'color', colors(1,:))
loglog(N2.^4, t2_implicit_add, 's-', 'color', colors(2,:))
loglog(N2.^4, t2_bsxfun_pow, '^-', 'color', colors(1,:))
loglog(N2.^4, t2_implicit_pow, '^-', 'color', colors(2,:))
legend('Addition, bsxfun', 'Addition, implicit', 'Power, bsxfun', 'Power, implicit')
票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42559922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档