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

Sean Kelly sean at invisibleduck.org
Fri Jun 20 10:57:24 PDT 2008


== Quote from Jarrett Billingsley (kb3ctd2 at yahoo.com)'s article
> "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.

My mistake for assuming the compiler would generate the appropriate code for
this.  I'm fixing this in Tango today, assuming no problems crop up.


Sean



More information about the Digitalmars-d mailing list