Matlab - bsxfun不再比repmat快吗?

时间:2015-02-25 15:20:37

标签: arrays matlab bsxfun

我正在尝试找到在Matlab中标准化矩阵的最快方法(零均值,单位方差列)。这一切都归结为将相同操作应用于矩阵中所有行的最快方法。我读过的每篇帖子都得出了相同的结论: 使用bsxfun代替repmat 。 Mathworks编写的这篇文章就是一个例子:http://blogs.mathworks.com/loren/2008/08/04/comparing-repmat-and-bsxfun-performance/

但是,在我自己的计算机上尝试这个时,repmat总是更快。以下是我使用与文章中相同代码的结果:

m = 1e5;
n = 100;
A = rand(m,n);

frepmat = @() A - repmat(mean(A),size(A,1),1);
timeit(frepmat)

fbsxfun = @() bsxfun(@minus,A,mean(A));
timeit(fbsxfun)

结果:

ans =

    0.0349


ans =

    0.0391

事实上,无论输入矩阵有多小或多大,我都无法让bsxfun在这种情况下比repmat表现得更好。

有人可以解释一下吗?

1 个答案:

答案 0 :(得分:11)

您正在阅读的大多数建议,包括Loren的博客文章,可能都是指旧版本的MATLAB,其中bsxfunrepmat快得多。在R2013b中(请参阅链接中的“性能”部分),repmat已重新实现,以便在应用于数字,字符和逻辑参数时提供较大的性能改进。在最近的版本中,它可以与bsxfun大致相同的速度。

对于它的价值,在我的R2014a机器上我得到了

m = 1e5;
n = 100;
A = rand(m,n);

frepmat = @() A - repmat(mean(A),size(A,1),1);
timeit(frepmat)

fbsxfun = @() bsxfun(@minus,A,mean(A));
timeit(fbsxfun)

ans =
      0.03756
ans =
     0.034831

所以看起来bsxfun仍然快一点,但并不多 - 而且在你的机器上看起来情况恰恰相反。当然,如果您改变A的大小或您正在应用的操作,这些结果可能会再次变化。

可能还有其他理由偏好另一种解决方案,例如优雅(如果可能的话,我更喜欢bsxfun。)


修改:评论者要求选择bsxfun的特定原因,这意味着它可以使用比repmat更少的内存,避免使用{{1}的临时副本没有。

我认为事实并非如此。例如,打开任务管理器(或Linux / Mac上的等效项),监视内存级别,然后键入:

repmat

(调整>> m = 1e5; n = 8e3; A = rand(m,n); >> B = A - repmat(mean(A),size(A,1),1); >> clear B >> C = bsxfun(@minus,A,mean(A)); >> clear C m,直到图中可以看到跳转,但内存不足则不会那么大。

我从nrepmat看到完全相同的行为,即内存平稳上升到新的水平(基本上是bsxfun的两倍),没有临时的额外峰值

即使操作就地完成也是如此。再次,观察内存并输入:

A

同样,我从>> m = 1e5; n = 8e3; A = rand(m,n); >> A = A - repmat(mean(A),size(A,1),1); >> clear all >> m = 1e5; n = 8e3; A = rand(m,n); >> A = bsxfun(@minus,A,mean(A)); repmat看到了完全相同的行为,即内存上升到一个峰值(基本上是bsxfun的两倍),然后再回落到上一级。

所以我担心Arepmat之间在速度或内存方面看不出太多技术差异。我对bsxfun的偏好实际上只是个人偏好,因为它感觉更优雅。