Performance of tables slower than built in?
JS
JS.Music.Works at gmail.com
Wed May 22 00:22:09 UTC 2019
I am trying to create some fast sin, sinc, and exponential
routines to speed up some code by using tables... but it seems
it's slower than the function itself?!?
The code below uses matplotlibd but is not necessary. The timing
code is lower.
Ideally I'd like to have quadratic interpolation and all that but
if the code is going to be slower and less accurate then what is
the point?
Surely I'm doing something wrong?
I wasn't able to test this with LDC because it's giving me linker
errors for some reason.
I'm also curious as to what D is using internally in the first
place.
The generation uses a quarter sin since the waveform is
symmetric. This does slow down the code a little but I can't
imagine the few ops it uses to do this is more costly than
whatever is used for computing sin.
import std.math;
import std.range;
import std.random;
import std.algorithm;
import plt = matplotlibd.pyplot;
import std.stdio, core.stdc.stdlib;
__gshared double[] QuarterSinTab;
auto GenQuarterSinTab(int res = 4*100)
{
res++; // Add extra endpoint to make linear interpolation
easier/faster
alias T = typeof(QuarterSinTab[0]);
if (QuarterSinTab !is null) free(QuarterSinTab.ptr);
QuarterSinTab = (cast(T*)malloc(T.sizeof*res))[0..res];
res--;
for(int i = 0; i < res; i++)
QuarterSinTab[i] = sin(PI*(i/cast(double)res));
QuarterSinTab[$-1] = QuarterSinTab[0];
}
/*
Uses the tabularized quarter sine and extends it to the full
range
*/
auto sinTab(string Method = "Linear")(typeof(QuarterSinTab[0]) x)
{
alias T = typeof(QuarterSinTab[0]);
auto len = QuarterSinTab.length - 1;
auto s = -1;
auto m = x - cast(int)x;
auto m2 = 1;
if (x < 0) { m = m + 1; s = 1; }
if ((abs(x) % 2) < 1) s = -s;
auto a = m*len;
auto ai = cast(int)(m*len);
switch(Method)
{
default:
case "Linear":
auto f = a - ai;
return s*((1 - f)*QuarterSinTab[ai] + f*QuarterSinTab[ai+1]);
case "Constant":
return s*QuarterSinTab[ai];
}
}
void main() {
GenQuarterSinTab;
auto x = iota(-10, 10, 0.01).map!(x => x * PI);
auto y = x.map!("sin(PI*a)");
auto z = x.map!((x){ return sin(PI*x) - sinTab(x);});
//plt.plot(x, y, "r-", ["label": "$y=sin(x)$"]);
plt.plot(x, z, "b-", ["label": "$y$"]);
plt.xlim(-5, 5);
plt.ylim(-0.001, 0.001);
plt.legend();
plt.show();
import std.datetime;
double xxx = 0;
StopWatch sw;
sw.start();
for(double i = 0; i < 10000000; i++) xxx += sinTab(i);
auto t = sw.peek().msecs;
writeln(t);
sw.stop();
writeln(xxx);
xxx = 0;
sw.reset();
sw.start();
for(double i = 0; i < 10000000; i++) xxx += sin(PI*i);
t = sw.peek().msecs;
writeln(t);
sw.stop();
}
More information about the Digitalmars-d-learn
mailing list