digitalmars.D.learn - speed of low-level C funcs: example of memmove
- spir (106/106) Apr 09 2011 Hello,
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