【问题标题】:Fastest way to sum the elements of a matrix求和矩阵元素的最快方法
【发布时间】:2023-03-25 13:21:02
【问题描述】:

我的代码效率存在一些问题。基本上我的代码是这样工作的:

a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
sum(a);

求解该矩阵所有元素之和的最快方法是什么?

【问题讨论】:

  • 这小段代码的性能问题是什么?据我所知,没有比sum 计算总和更快的方法了。但是,您可以像这样更轻松地生成a-matrix:n = 1:50000; a = 10*n - 5;
  • (1) 哎呀。我的错。刚刚编辑了帖子。 (2) 我只是想知道是否有更快的方法来求和。 :)

标签: matlab sum processing-efficiency memory-efficient space-efficiency


【解决方案1】:

首先你要删除你的 for 循环,使其成为向量乘法:

tic
a = zeros(1,50000);
b = [1:50000];
   a = 10.*b-5;
result = sum(a);
toc
Elapsed time is 0.008504 seconds.

另一种方法是简化您的操作,您将 1 到 50000 乘以 10 并减去 5 然后取总和(这是一个数字),相当于:

tic
result = sum(1:50000)*10 - 5*50000;
toc
Elapsed time is 0.003851 seconds.

或者如果你真的很喜欢数学(这是一种纯粹的数学表达方法):

tic
result = (1+50000)*(50000/2)*10 - 5*50000;
toc
Elapsed time is 0.003702 seconds.

如您所见,一点点数学运算可以比纯粹的高效编程做得更好,实际上,循环并不总是很慢,在您的情况下,循环实际上比矢量化方法更快:

tic
a = zeros(1,50000);
  for n = 1:50000
     a(n)=10.*n-5;
  end
sum(a);
toc
Elapsed time is 0.006431 seconds.

时间

让我们做一些时间,看看结果。底部提供了自己运行的功能。 execTime 的大致执行时间以秒为单位,impPercentage 的改进百分比以 % 为单位。

结果

  • OSX 10.11.4 上的 R2016a

                   execTime     impPercentage
                  __________    _____________
    loop          0.00059336         0       
    vectorized    0.00014494    75.574       
    adiel         0.00010468    82.359       
    math          9.3659e-08    99.984       
    

代码

以下函数可用于生成输出。请注意,它至少需要 R2013b 才能使用内置的 timeit-function 和 table

function timings
%feature('accel','on')      %// commented out because it's undocumented
cycleCount = 100;
execTime = zeros(4,cycleCount);
names = {'loop';'vectorized';'adiel';'math'};
w = warning;
warning('off','MATLAB:timeit:HighOverhead');
for k = 1:cycleCount
    execTime(1,k) = timeit(@()loop,1);
    execTime(2,k) = timeit(@()vectorized,1);
    execTime(3,k) = timeit(@()adiel,1);
    execTime(4,k) = timeit(@()math,1);
end
warning(w);
execTime = min(execTime,[],2);
impPercentage = (1 - execTime/max(execTime)) * 100;
table(execTime,impPercentage,'RowNames',names)


function result = loop
a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
result = sum(a);

function result = vectorized
b = 1:50000;
a = 10.*b - 5;
result = sum(a);

function result = adiel
result = sum(1:50000)*10 - 5*50000;

function result = math
result = (1+50000)*(50000/2)*10 - 5*50000;

【讨论】:

  • 这些时间不具有代表性,因为您只执行了一次。执行 10'000 次或更多次,可以看到矢量化解决方案的速度提高了 3 倍以上。
  • 为什么这一切......?只需 a=10*(1:50000)-5 比任何这些选项都快。
  • @Matt nope,我得到了类似的性能结果,你想分享你的代码/答案,以便我可以尝试重新创建它吗?
  • @Matt 这个问题已被编辑到社区 wiki,也许其他人可以解释/编辑我们得到的不同结果。
  • 感谢您添加计时性能@Matt,我在测试时使用的是 2010b 版本。
猜你喜欢
  • 2012-07-02
  • 2013-07-02
  • 1970-01-01
  • 2014-06-15
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多