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

Reply via email to