matlab 乘法_MATLAB代码提速的冷门小技巧: 用"连乘法"代替"整数幂"...

4ee80d88f313a64b9400f153d8a84bf5.png
知乎视频​www.zhihu.com
zhihu-card-default.svg

元素级别的整数幂的官方语法是a.^n, n是一个整数.

如果n是正整数的话, 等价于a.*a.*a......*a, n个a连乘.

如果n是负整数的话, 等价于1./(a.*a.*a......*a), -n个a连乘, 然后取倒数.

既然是等价的, 因此, 理论上, 整数幂与连乘这两种方法速度应该是一样的.

如果整数幂的代码实现上用了"快速幂"算法, 整数幂速度会更快.

但是实际测试发现, 竟然是连乘法速度更快! 很可能是因为MATLAB内部实现幂运算的时候, 并没有考虑整数幂这样的特殊幂, 而是将n当成一般的实数来实现的.

测试代码如下:

function testpow()
%function to compare integer powers with repeated multiplication

disp('^2')
rng(0)
a = randn(10000, 100);
tic; a .^ 2; t1 = toc;
tic; a .* a; t2 = toc;
disp(t1 / t2)

disp('^-2')
rng(0)
a = randn(10000, 100);
tic; a .^ -2; t1 = toc;
tic; 1./(a .* a); t2 = toc;
disp(t1 / t2)

disp('^3')
rng(0)
a = randn(10000, 100);
tic; a .^ 3; t1 = toc;
tic; a .* a .* a; t2 = toc;
disp(t1 / t2)

disp('^-3')
rng(0)
a = randn(10000, 100);
tic; a .^ -3; t1 = toc;
tic; 1./(a .* a .* a); t2 = toc;
disp(t1 / t2)

disp('^4')
rng(0)
a = randn(10000, 100);
tic; a .^ 4; t1 = toc;
tic; a .* a .* a .* a; t2 = toc;
disp(t1 / t2)

disp('^5')
rng(0)
a = randn(10000, 100);
tic; a .^ 5; t1 = toc;
tic; a .* a .* a .* a .* a; t2 = toc;
disp(t1 / t2)

disp('^6')
rng(0)
a = randn(10000, 100);
tic; a .^ 6; t1 = toc;
tic; a .* a .* a .* a .* a .* a; t2 = toc;
disp(t1 / t2)

disp('^7')
rng(0)
a = randn(10000, 100);
tic; a .^ 7; t1 = toc;
tic; a .* a .* a .* a .* a .* a .* a; t2 = toc;
disp(t1 / t2)

disp('^-7')
rng(0)
a = randn(10000, 100);
tic; a .^ -7; t1 = toc;
tic; 1./(a .* a .* a .* a .* a .* a .* a); t2 = toc;
disp(t1 / t2)

disp('^8')
rng(0)
a = randn(10000, 100);
tic; a .^ 8; t1 = toc;
tic; a .* a .* a .* a .* a .* a .* a .* a; t2 = toc;
tic;
a = a .* a;
a = a .* a;
a = a .* a;
t3 = toc;
disp(t1 / t2)
disp(t1 / t3)

disp('^16')
rng(0)
a = randn(10000, 100);
tic; a .^ 16; t1 = toc;
tic; res = a .* a .* a .* a .* a .* a .* a .* a .* a .* a .* a .* a .* a .* a .* a .* a; t2 = toc;
tic;
a = a .* a;
a = a .* a;
a = a .* a;
res2 = a .* a;
t3 = toc;
disp(t1 / t2)
disp(t1 / t3)

max(abs(res - res2), [], 'all')

end

测试结果如下:

>> testpow
^2
0.7103
^-2
13.4001
^3
14.7536
^-3
14.2360
^4
14.5099
^5
13.3880
^6
14.2554
^7
11.4277
^-7
15.2771
^8
9.7430
16.1683
^16
20.0377
11.3064
ans =
3.0518e-05

改变测试数据a, 数值上会发生变化, 但是基本结论是不变的:

1 整数幂测试, 除去那些过于trival的例子, 比如a的一次, a的0次, 发现基本上都是"连乘法"速度更快, 除了a的二次方.

2 "连乘法"甚至有可能比我自己手动实现的"快速幂"更快!

总结:

1 由于我无法看到"times"函数或者"power"函数的内部实现, 因此, 我没有办法解释这样的现象.

2 测试发现"连乘法"要比"整数幂"运算要快得多(除了二次方以外), 应用这个测试结论, 可以用在代码提速上.

创作不易, 请大家"素质三连": 点赞, 收藏, 分享.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值