X[]==Y[] is 7X slower than it should be -- why?

Jarrett Billingsley kb3ctd2 at yahoo.com
Fri Jun 20 10:40:25 PDT 2008


"Don" <nospam at nospam.com.au> wrote in message 
news:g3ggq5$ui5$1 at digitalmars.com...

> What's it doing? Is it doing a byte-by-byte comparison? (it shouldn't do 
> that even for strings). Is it doing bounds checking for every array 
> element?? (even with -release -O)

See dmd/src/phobos/internal/adi.d  The important function here is:

extern (C) int _adEq(Array a1, Array a2, TypeInfo ti)
{
    if (a1.length != a2.length)
        return 0;

    auto sz = ti.tsize();
    auto p1 = a1.ptr;
    auto p2 = a2.ptr;

    if (sz == 1)
        // We should really have a ti.isPOD() check for this
        return (memcmp(p1, p2, a1.length) == 0);

    for (size_t i = 0; i < a1.length; i++)
    {
        if (!ti.equals(p1 + i * sz, p2 + i * sz))
            return 0;
    }

    return 1;
}

If the size of an element is 1 (bytes, chars, bools), it just does memcmp. 
There's even a comment in there that memcmp should be used if the type is 
POD (plain old data, which uints are).  But otherwise, it uses the RTTI 
.equals function to compare the elements, and it doesn't even use parallel 
pointers, it does manual indexing for each element.  .equals will, for 
uints, just return true if they are equal.

What flabbergasts me is that in the uint[] typeinfo class, there is an 
equals method that uses memcmp, but it's not used unless you explicitly call 
it (or if you have a uint[][]).  Try doing

bool b = typeid(uint[]).equals(&X[], &Y[]);

and see what kind of performance you get. 





More information about the Digitalmars-d mailing list