Improve performance of linspace

7 ビュー (過去 30 日間)
Shane
Shane 2015 年 4 月 21 日
編集済み: Jan 2015 年 9 月 29 日
I am needing to greatly improve the performance of a line of code. I need to run this line of code millions of times. But it currently takes ~.7 second to run it once!
The code is as follows:
ShotBinsX = 0.5*sin(linspace(-1*SlowMirrorPhase,...
(2*pi*NumSlowMirrorPeriods)-SlowMirrorPhase,...
ShotsPerFrame+1)) + 0.5;
Where SlowMirrorPhase will take values from 1:12500, and NumSlowMirrorPeriod will take values from 1:~1000, and ShotsPerFrame will vary, but not exceed 10 million or so, but in many cases be in the millions range or less.
Any ideas on how to make it faster?!

回答 (4 件)

Matt J
Matt J 2015 年 9 月 28 日
編集済み: Stephen23 2015 年 9 月 29 日
I'm not sure how you're looping right now, but if you write your loops as follows, you reduce the number of linspace evaluations by a factor of 12500 as compared to doing it for all combinations of all 3 variables.
for ShotsPerFrame=... : 1e7
for NumSlowMirrorPeriods=1:1000
LinspaceTerm = linspace(0, 2*pi*NumSlowMirrorPeriods, ShotsPerFrame+1);
for SlowMirrorPhase=1:12500
ShotBinsX = 0.5*sin(LinspaceTerm-SlowMirrorPhase) + 0.5;
end
end
end
The first term involving linspace can be precomputed
  2 件のコメント
Matt J
Matt J 2015 年 9 月 28 日
編集済み: Stephen23 2015 年 9 月 29 日
You can also vectorize the innermost loop to cut down on some overhead,
SlowMirrorPhase = (1:12500).';
for ShotsPerFrame=... : 1e7
for NumSlowMirrorPeriods=1:1000
LinspaceTerm = linspace(0, 2*pi*NumSlowMirrorPeriods, ShotsPerFrame+1);
sineArg=bsxfun(@minus,LinspaceTerm,SlowMirrorPhase);
ShotBinsX = 0.5*sin(sineArg) + 0.5;
end
end
Matt J
Matt J 2015 年 9 月 29 日
Here's an even better version. Now you're only calling linspace once per value of ShotsPerFrame.
SlowMirrorPhase = (1:12500).';
for ShotsPerFrame=... : 1e7
LinspaceTerm = linspace(0, 2*pi, ShotsPerFrame+1);
for NumSlowMirrorPeriods=1:1000
sineArg=bsxfun(@minus,LinspaceTerm*NumSlowMirrorPeriods,...
SlowMirrorPhase);
ShotBinsX = 0.5*sin(sineArg) + 0.5;
end
end

サインインしてコメントする。


pfb
pfb 2015 年 4 月 21 日
are you sure that it is a matter of linspace? Did you try profiling your code?
I'd say the "problem" is in the sin function, which I expect to be much slower than linspace itself.
Maybe you can tweak your grid a little bit in order to take advantage of the periodicity of the sin function.

Jeff Lentz
Jeff Lentz 2015 年 9 月 28 日
I agree with pfb that sin could be a bigger problem than linspace.
But I have observed slow performance in linspace before. I wrote my own linspace function that is about 4 times faster than the built-in MATLAB linspace (tested in 2012a but not very thoroughly.) However, it WILL have small amounts of rounding error when compared to the original.
function y = linspace(a, b, n)
y = (b-a)/(n-1)*(0:n-1) + a;
end

Jan
Jan 2015 年 9 月 29 日
編集済み: Jan 2015 年 9 月 29 日
What about inlining linspace?
d1 = -SlowMirrorPhase; % Faster than -1 * ...
d2 = (2*pi*NumSlowMirrorPeriods) - SlowMirrorPhase;
n = ShotsPerFrame + 1;
k = 2*pi*NumSlowMirrorPeriods; % Move bevor the loop
% X = [d1 + (0:n-2) .* (d2 - d1)/n1, d2]
X = [-SlowMirrorPhase :k: ((n-2)*k) - SlowMirrorPhase) ./ ShotsPerFrame , d2];
ShotBinsX = sin(X) / 2 + 0.5;

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by