Robert Jacques wrote:
On Sun, 27 Sep 2009 09:11:38 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
Robert Jacques wrote:
On Sat, 26 Sep 2009 21:32:13 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
Consider two objects a and b with a of class type. Currently, the
expression a == b is blindly rewritten as a.opEquals(b). I argue it
should be rewritten into a call to an (imaginary/inlined) function
equalObjects(a, b), with the following definition:
bool equalObjects(T, U)(T a, U b) if (is(T == class))
{
static if (is(U == class))
{
if (b is null) return a is null;
if (a is null) return b is null;
}
else
{
enforce(a !is null);
}
return a.opEquals(b);
}
This hoists the identity test outside the opEquals call and also
deals with null references. What do you think?
Andrei
I like this. I think optimizing away opEquals for identical objects
would also be a good idea:
static if (is(U == class))
if(a is b || a is null || b is null) return a is b;
else
enforce(a !is null);
This code has an inefficiency, it seems, because it makes a bit more
checks than necessary (e.g. checks a is b twice). Let's simplify:
bool equalObjects(T, U)(T a, U b) if (is(T == class))
{
static if (is(U == class))
{
if (a is b) return true;
if (b is null || a is null) return false;
}
else
{
enforce(a !is null);
}
return a.opEquals(b);
}
Andrei
Are the extra branch and return statement faster?
Just as fast. Short-circuit evaluation also generates code with branches.
Besides, I thought the
optimizer would cache a is b:
auto a_is_b = a is b;
if (a_is_b || b is null || a is null) return a_is_b;
I'm trying to not rely on such...
Andrei