コードの効率に問題があります。基本的に、私のコードは次のように機能します。
a = zeros(1,50000);
for n = 1:50000
a(n) = 10.*n - 5;
end
sum(a);
この行列のすべての要素の合計を解く最速の方法は何ですか?
コードの効率に問題があります。基本的に、私のコードは次のように機能します。
a = zeros(1,50000);
for n = 1:50000
a(n) = 10.*n - 5;
end
sum(a);
この行列のすべての要素の合計を解く最速の方法は何ですか?
まず、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;