1

コードの効率に問題があります。基本的に、私のコードは次のように機能します。

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

この行列のすべての要素の合計を解く最速の方法は何ですか?

4

1 に答える 1

3

まず、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       
    

コード

次の関数を使用して、出力を生成できます。組み込み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;
于 2016-04-06T09:45:43.000 に答える