putting more smarts into a == b

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Sep 27 08:19:33 PDT 2009


Robert Jacques wrote:
> On Sun, 27 Sep 2009 09:11:38 -0400, Andrei Alexandrescu 
> <SeeWebsiteForEmail at erdani.org> wrote:
> 
>> Robert Jacques wrote:
>>> On Sat, 26 Sep 2009 21:32:13 -0400, Andrei Alexandrescu 
>>> <SeeWebsiteForEmail at 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



More information about the Digitalmars-d mailing list