putting more smarts into a == b

Robert Jacques sandford at jhu.edu
Sun Sep 27 08:13:28 PDT 2009


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? 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;



More information about the Digitalmars-d mailing list