Improve performance of linspace

8 views (last 30 days)
Shane
Shane on 21 Apr 2015
Edited: Jan on 29 Sep 2015
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?!

Answers (4)

Matt J
Matt J on 28 Sep 2015
Edited: Stephen23 on 29 Sep 2015
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 Comments
Matt J
Matt J on 28 Sep 2015
Edited: Stephen23 on 29 Sep 2015
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 on 29 Sep 2015
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

Sign in to comment.


pfb
pfb on 21 Apr 2015
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 on 28 Sep 2015
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 on 29 Sep 2015
Edited: Jan on 29 Sep 2015
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;

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!