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();
}

Reply via email to