On Thursday, 1 September 2016 at 09:53:59 UTC, Miguel L wrote:
On Thursday, 1 September 2016 at 09:36:16 UTC, Miguel L wrote:
Hi

I recently needed a very optimized array rotation algorithm, so I did this benchmark, hope you find it interesting. I am a bit surprised by the poor results of std.algorithm.bringToFront:

[...]

Sorry Rotate4 had a bug, there was an extra for that was not neccesary, this is the correct implementation:

void Rotate4(T)(T[] input, long n) pure
{
        /* 1,2,3,4,5,6,7,8 - 2 -
         * 7,2,3,4,5,6,1,8 - a=0 b=8-2=6
         * 7,8,3,4,5,6,1,2 - a=1 b=7
         * 7,8,1,4,5,6,3,2 - a=2 b=6
         * 7,8,1,2,5,6,3,4 - a=3 b=7
         * 7,8,1,2,3,6,5,4 - a=4 b=6
         * 7,8,1,2,3,4,5,6 - a=5 b=7
--------------------
       1,2,3,4,5,6,7,8,9 - 3 -
         * 7,2,3,4,5,6,1,8,9 - a=0 b=9-3=6
         * 7,8,3,4,5,6,1,2,9 - a=1 b=7
         * 7,8,9,4,5,6,1,2,3 - a=2 b=8
         * 7,8,9,1,5,6,4,2,3 - a=3 b=6
         * 7,8,9,1,2,6,4,5,3 - a=4 b=7
         * 7,8,9,1,2,3,4,5,6 - a=5 b=8
         */
        if(n<0)
                n=input.length+n;

        long a=0,b=input.length-n;
        T tmp;

        while(a<input.length-n-1)
        {
                tmp=input[b];
                input[b]=input[a];
                input[a]=tmp;
                ++a;
                ++b;
                if(b>=input.length)
                        {
                        b=input.length-n;
                        }
        }

}

Very sorry again: Rotate4 was not correct with negative offsets.
This implementation works correctly:

void Rotar4(T)(T[] input, long n) pure
{
        /* 1,2,3,4,5,6,7,8 - 2 -
         * 7,2,3,4,5,6,1,8 - a=0 b=8-2=6
         * 7,8,3,4,5,6,1,2 - a=1 b=7
         * 7,8,1,4,5,6,3,2 - a=2 b=6
         * 7,8,1,2,5,6,3,4 - a=3 b=7
         * 7,8,1,2,3,6,5,4 - a=4 b=6
         * 7,8,1,2,3,4,5,6 - a=5 b=7
         *

         * 1,2,3,4,5,6,7,8 - -2 -
         * 1,8,3,4,5,6,7,2 - a=7 b=1
         * 7,8,3,4,5,6,1,2 - a=6 b=0
         * 7,6,3,4,5,8,1,2 - a=5 b=1
         * 5,6,3,4,7,8,3,4 - a=4 b=0
         * 3,6,5,4,7,8,1,2 - a=3 b=1
         * 3,4,5,6,7,8,1,2 - a=2 b=0

--------------------
       1,2,3,4,5,6,7,8,9 - 2 -
         * 7,2,3,4,5,6,1,8,9 - a=0 b=9-3=6
         * 7,8,3,4,5,6,1,2,9 - a=1 b=7
         * 7,8,9,4,5,6,1,2,3 - a=2 b=8
         * 7,8,9,1,5,6,4,2,3 - a=3 b=6
         * 7,8,9,1,2,6,4,5,3 - a=4 b=7
         * 7,8,9,1,2,3,4,5,6 - a=5 b=8
         */
        long a,b;
        T tmp;

        if(n>0)
        {
                a=0;
                b=input.length-n;               
                
                while(a<input.length-n)
                {
                        tmp=input[b];
                        input[b]=input[a];
                        input[a]=tmp;
                        ++a;
                        ++b;
                        if(b>=input.length)
                                b=input.length-n;
                }
        }
        else
        {
                a=input.length-1;
                long b0=-n-1;
                b=b0;           
                
                while(a>=-n)
                {
                        tmp=input[b];
                        input[b]=input[a];
                        input[a]=tmp;
                        --a;
                        --b;
                        if(b<0)
                                b=b0;
                }
        }       

}

Also, forgot to specify I am using LDC with -05.
Updated benchmark results:

Rotate0: 0.344186s
Rotate1: 1.76369s
Rotate2: 0.169968s
Rotate3: 0.354091s
Rotate4: 0.156231s

Reply via email to