www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - speed of low-level C funcs: example of memmove

Hello,

To insert of delete an array slice, I tried to use C's memmove, thinking it 
would be far faster than "manually" copying bit per bit (by any kind of magic). 
But I still wrote a D versions just to check what the actual speed gain is. To 
my great surprise, the C-memmove and D-manual versions perform *exactly* at the 
same speed (considering measure imprecision).
Note: this remains true when elements are bigger; speed slows down slowly (eg 
dchar's take only 1/3 more time).

Any comment or explanation welcome. Below the code.

Denis

============= code =============================================
import std.date     : getUTCtime, d_time;
import std.c.string : memmove;
// C interface: void *memmove(void *dest, const void *src, size_t n);

void shiftEndPartC (E) (ref E[] array, size_t source, size_t dest) {
     // Record length before possible extension.
     auto length     = array.length;
     int offset      = dest - source;

     // If move up, extend array to make place.
     if (offset > 0)
         array.length += offset;

     // Shift slice.
     auto pDest      = cast(void*)(&(array[dest]));
     auto pSource    = cast(void*)(&(array[source]));
     size_t size     = (length - source) * E.sizeof;
     memmove(pDest, pSource, size);

     // If move down, compress array.
     if (offset < 0)
         array.length += offset;
}
void shiftEndPartD (E) (ref E[] array, size_t source, size_t dest) {
     // Record length before possible extension.
     auto length     = array.length;
     int offset      = dest - source;

     // If move up, extend array & shift backwards.
     if (offset > 0) {
         array.length += offset;
         for (size_t i=length-1 ; i>=source ; i--)
             array[i+offset] = array[i];
     }

     // If move down, shift forwards & compress array.
     if (offset < 0) {
         for (size_t i=source ; i<length ; i++)
             array[i+offset] = array[i];
         array.length += offset;
     }
}

void testFuncs () {
     char[] s;

     // C memmove
     s = "0123456789".dup;
     writeln(s);
     // Insert slice.
     s.shiftEndPartC(3,5);
     s[3..5] = "--";
     writeln(s);
     // Delete slice.
     s.shiftEndPartC(5,3);
     writeln(s);
     writeln();

     // D manual
     s = "0123456789".dup;
     writeln(s);
     // Insert slice.
     s.shiftEndPartD(3,5);
     s[3..5] = "--";
     writeln(s);
     // Delete slice.
     s.shiftEndPartD(5,3);
     writeln(s);
     writeln();
}
void chrono () {
     char[] s;
     d_time t;
     enum N = 1_000_000;

     // C memmove
     s = "0123456789".dup;
     t = getUTCtime();
     foreach (_ ; 0..N) {
         s.shiftEndPartC(3,5);
         s[3..5] = "--";
         s.shiftEndPartC(5,3);
     }
     t = getUTCtime() - t;
     writefln("C time: %s", t);

     // D manual
     s = "0123456789".dup;
     t = getUTCtime();
     foreach (_ ; 0..N) {
     s.shiftEndPartD(3,5);
     s[3..5] = "--";
     s.shiftEndPartD(5,3);
     }
     t = getUTCtime() - t;
     writefln("D time: %s", t);
}

unittest {
//~     testFuncs();
     chrono();
}
void main () {}
-- 
_________________
vita es estrany
spir.wikidot.com
Apr 09 2011