speed of low-level C funcs: example of memmove
spir
denis.spir at gmail.com
Sat Apr 9 10:08:12 PDT 2011
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
More information about the Digitalmars-d-learn
mailing list