介绍
是否辩论bsxfun
优于repmat
反之亦然已经持续了像永远。 在这篇文章中,我们会尝试比较不同的内置插件与MATLAB船怎么打出来反对repmat
在它们的运行时性能方面等同,希望得出一些有意义的结论了出来。
结识BSXFUN内置插件
如果官方文件从MATLAB环境,或通过拉出Mathworks公司的网站 ,可以看到由支持的内置函数的完整列表bsxfun
。 这份名单有浮点,关系和逻辑运算功能。
在MATLAB 2015A
,支持逐元素的浮点运算是:
- @plus(求和)
- @minus(减法)
- @times(乘法)
- @rdivide(右分)
- @ldivide(左分)
- @pow(功率)
- @rem(余数)
- @mod(模数)
- @ ATAN2(四个象限反正切)
- @ atan2d(以度为单位的四象限反正切)
- @hypot(平方和的平方根)。
第二组由逐元素关系操作的那些是:
- @eq(相等)
- @ne(不等于)
- @lt(小于)
- @le(小于或等于)
- @gt(大于)
- @ge(大于或等于)。
逻辑运算的第三和最后一组包括如下所列:
- @and(逻辑和)
- @or(逻辑或)
- @xor(逻辑异或)。
请注意,我们已经排除了两个内置插件@max (maximum)
和@min (minimum)
从我们的对比测试中,因为可能有很多方法可以实现他们的repmat
等价物。
比较型号
要真正比较的表演repmat
和bsxfun
,我们需要确保时序只需要覆盖预期的操作。 因此,像bsxfun(@minus,A,mean(A))
将不理想,因为它具有计算mean(A)
这里面bsxfun
通话,但是无意义的,时间上可能。 取而代之的是,我们可以使用另一输入B
相同大小的mean(A)
因此,我们可以使用: A = rand(m,n)
B = rand(1,n)
其中, m
和n
是大小参数,我们可以改变和研究基于它们的性能。 这将在下一节中列出了基准测试准确完成。
该repmat
和bsxfun
版本这些输入操作会看起来像这些-
REPMAT: A + repmat(B,size(A,1),1)
BSXFUN: bsxfun(@plus,A,B)
标杆
最后,我们在这篇文章看这两个家伙打出来的症结所在。 我们已经分开了标杆成三组,一个用于浮点操作,另一个用于关系,第三个用于逻辑运算。 我们延长了比较模型早些时候所有的这些操作进行讨论。
SET1:浮点运算
这里的第一套基准的浮点运算用代码的repmat
和bsxfun
-
datasizes = [ 100 100; 100 1000; 100 10000; 100 100000;
1000 100; 1000 1000; 1000 10000;
10000 100; 10000 1000; 10000 10000;
100000 100; 100000 1000];
num_funcs = 11;
tsec_rep = NaN(size(datasizes,1),num_funcs);
tsec_bsx = NaN(size(datasizes,1),num_funcs);
for iter = 1:size(datasizes,1)
m = datasizes(iter,1);
n = datasizes(iter,2);
A = rand(m,n);
B = rand(1,n);
fcns_rep= {@() A + repmat(B,size(A,1),1),@() A - repmat(B,size(A,1),1),...
@() A .* repmat(B,size(A,1),1), @() A ./ repmat(B,size(A,1),1),...
@() A.\repmat(B,size(A,1),1), @() A .^ repmat(B,size(A,1),1),...
@() rem(A ,repmat(B,size(A,1),1)), @() mod(A,repmat(B,size(A,1),1)),...
@() atan2(A,repmat(B,size(A,1),1)),@() atan2d(A,repmat(B,size(A,1),1)),...
@() hypot( A , repmat(B,size(A,1),1) )};
fcns_bsx = {@() bsxfun(@plus,A,B), @() bsxfun(@minus,A,B), ...
@() bsxfun(@times,A,B),@() bsxfun(@rdivide,A,B),...
@() bsxfun(@ldivide,A,B), @() bsxfun(@power,A,B), ...
@() bsxfun(@rem,A,B), @() bsxfun(@mod,A,B), @() bsxfun(@atan2,A,B),...
@() bsxfun(@atan2d,A,B), @() bsxfun(@hypot,A,B)};
for k1 = 1:numel(fcns_bsx)
tsec_rep(iter,k1) = timeit(fcns_rep{k1});
tsec_bsx(iter,k1) = timeit(fcns_bsx{k1});
end
end
speedups = tsec_rep./tsec_bsx;
SET2:关系运算
该基准测试代码,以时间关系操作将取代fcns_rep
和fcns_bsx
与这些同行前面的基准测试代码-
fcns_rep = {
@() A == repmat(B,size(A,1),1), @() A ~= repmat(B,size(A,1),1),...
@() A < repmat(B,size(A,1),1), @() A <= repmat(B,size(A,1),1), ...
@() A > repmat(B,size(A,1),1), @() A >= repmat(B,size(A,1),1)};
fcns_bsx = {
@() bsxfun(@eq,A,B), @() bsxfun(@ne,A,B), @() bsxfun(@lt,A,B),...
@() bsxfun(@le,A,B), @() bsxfun(@gt,A,B), @() bsxfun(@ge,A,B)};
SET3:逻辑运算
最后一组标杆代码将使用逻辑运算此处所列的 -
fcns_rep = {
@() A & repmat(B,size(A,1),1), @() A | repmat(B,size(A,1),1), ...
@() xor(A,repmat(B,size(A,1),1))};
fcns_bsx = {
@() bsxfun(@and,A,B), @() bsxfun(@or,A,B), @() bsxfun(@xor,A,B)};
请注意,对于该特定组,输入数据,A和B分别为所需的逻辑阵列。 所以,我们在前面的基准测试代码来创建逻辑阵列做这些编辑 -
A = rand(m,n)>0.5;
B = rand(1,n)>0.5;
运行时和观察
该基准测试代码已在此系统配置运行:
MATLAB Version: 8.5.0.197613 (R2015a)
Operating System: Windows 7 Professional 64-bit
RAM: 16GB
CPU Model: Intel® Core i7-4790K @4.00GHz
因此与获得的加速比bsxfun
超过repmat
运行基准测试之后绘制的三组如下所示。
A.浮点运算:
一些看法可以从加速曲线图可以得出:
- 该特别是两个很好的加速比例
bsxfun
是atan2
和atan2d
。 - 其次在该列表是提升执行与左,右除法运算
30% - 50%
以上的repmat
等价代码。 - 要在该列表中进一步下跌的其余
7
操作,其速度提升似乎非常接近统一,因此需要进一步的检查。 在加速的情节可以被缩小到只是那些7
如下图所示的操作-
基于上述情节,人们可以看到,禁止一次性例@hypot
和@mod
, bsxfun
仍然表现优于10%左右repmat
这些7
操作。
B.关系运算:
这是由内置支持的关系运算未来6第二套标杆bsxfun
。
在加速的情节看上面,而忽略了那间可比的运行时间开始的情况下bsxfun
和repmat
,人们可以很容易地看到bsxfun
赢得了这些关系操作。 随着接触的加速10x
, bsxfun
将永远是最好的这些情况。
C.逻辑操作:
这是第三套为基准所支持的其余3个内置的逻辑运算的bsxfun
。
忽视了对一次性可比的运行情况@xor
在一开始, bsxfun
似乎有占上风这组逻辑操作了。
结论
- 当使用关系和逻辑运算工作,
repmat
可以很容易地有利于遗忘bsxfun
。 对于的情况下休息,一个仍然可以坚持bsxfun
如果一次性例, 5 - 7%
较低性能是可以容忍的。 - 使用带有关系和逻辑操作时,看到的那种巨大的性能提升的
bsxfun
,可以考虑使用bsxfun
对处理数据ragged patterns
,类似的性能优势电池阵列。 我喜欢把这些解决案件使用那些bsxfun
的屏蔽能力 。 这基本上意味着,我们创建逻辑阵列,即口罩bsxfun
,其可以被用于交换单元阵列和数字阵列之间的数据。 的优点之一为具有数字数组可行数据是量化方法可以被用来处理它们。 同样,由于bsxfun
是矢量一个很好的工具,你会发现自己使用它再次在同一个问题的工作下来,所以有更多的理由去了解bsxfun
。 少数溶液的情况下,我能够探索这样的方法是此处链接为读者的利益: 1 , 2 , 3 , 4 , 5 。
未来的工作
目前的工作重点是随着一名维复制数据repmat
。 现在, repmat
可以沿着多个维度复制等做bsxfun
其扩张等同于重复。 因此,这将是有趣执行上复制并展开的类似试验在多个维度与这两个功能。