Wow, the patch is impressive! Thanks, I support it.

Interestingly it did not result in notable difference in XMLMark.
Having != implementation based on your Equals() implementation
resulted in the best improvement. I think 2% difference in String
inequality is worthy of having different implementation, but just
my 2 cents.

Atsushi Eno

Marek Safar wrote:
> Hello,
>> I noticed that String operator != just reuses == i.e. a != b
>> returns ! (a == b). It could be more effective if operator!=
>> has actual implementation code. Also, string.Equals() currently
>> calls operator!= which performs extraneous null check (maybe
>> static invocation was faster?).
>>
>> As far as I tried with XMLmark, the attached patch certainly
>> improves performance (though not big, about 2%). If it looks
>> good feel free to apply to trunk.
>>   
> I think it is not worthwhile to duplicate all code because of 2 %.
> 
>> I noticed that string op_Equality is slow, about 2x than MS.
>> There might be chances to improve it.
>>   
> I tried to optimize internal method used for Equality and here are
> results of my string.Equal micro benchmark and patch (including both of
> them).
> 
> Micro benchmark results for P-III - 1,13 GHz
> 
> Microsoft runtime v 1.1 - 41,47 sec
> Microsoft runtime v 2.0 - 26,30 sec
> 
> Mono SVN HEAD - 44,00 sec
> Mono SVN HEAD -O=all - 42,09 sec
> 
> Patched Mono SVN HEAD - 26,32 sec
> Patched Mono SVN HEAD -O=all - 25,88 sec
> 
> Patch on Microsoft runtime v 2.0 - 21,65 sec
> 
> The last result I got when I tried to run my new code on Microsoft
> runtime (MS JIT). The result is best of all which basically means that
> we can still improve our JIT compiler ;-)
> 
> 
> For test on Microsoft runtime I used csc with /optimize+ option and mcs
> for Mono tests.
> 
> Any objections to the patch ?
> 
> 
> - Marek
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> Index: C:/CVSROOT/mcs/class/corlib/System/String.cs
> ===================================================================
> --- C:/CVSROOT/mcs/class/corlib/System/String.cs      (revision 57019)
> +++ C:/CVSROOT/mcs/class/corlib/System/String.cs      (working copy)
> @@ -72,28 +72,42 @@
>                       if (len != b.length)
>                               return false;
>  
> -                     if (len == 0)
> -                             return true;
> +                     fixed (char* s1 = &a.start_char, s2 = &b.start_char) {
> +                             char* s1_ptr = s1;
> +                             char* s2_ptr = s2;
>  
> -                     fixed (char * s1 = &a.start_char, s2 = &b.start_char) {
> -                             // it must be one char, because 0 len is done 
> above
> -                             if (len < 2)
> -                                     return *s1 == *s2;
> +                             while (len >= 8) {
> +                                     if (((int*)s1_ptr)[0] != 
> ((int*)s2_ptr)[0] ||
> +                                             ((int*)s1_ptr)[1] != 
> ((int*)s2_ptr)[1] ||
> +                                             ((int*)s1_ptr)[2] != 
> ((int*)s2_ptr)[2] ||
> +                                             ((int*)s1_ptr)[3] != 
> ((int*)s2_ptr)[3])
> +                                             return false;
>  
> -                             // check by twos
> -                             int * sint1 = (int *) s1, sint2 = (int *) s2;
> -                             int n2 = len >> 1;
> -                             do {
> -                                     if (*sint1++ != *sint2++)
> +                                     s1_ptr += 8;
> +                                     s2_ptr += 8;
> +                                     len -= 8;
> +                             }
> +
> +                             if (len >= 4) {
> +                                     if (((int*)s1_ptr)[0] != 
> ((int*)s2_ptr)[0] ||
> +                                             ((int*)s1_ptr)[1] != 
> ((int*)s2_ptr)[1])
>                                               return false;
> -                             } while (--n2 != 0);
>  
> -                             // nothing left
> -                             if ((len & 1) == 0)
> -                                     return true;
> +                                     s1_ptr += 4;
> +                                     s2_ptr += 4;
> +                                     len -= 4;
> +                             }
>  
> -                             // check the last one
> -                             return *(char *) sint1 == *(char *) sint2;
> +                             if (len > 1) {
> +                                     if (((int*)s1_ptr)[0] != 
> ((int*)s2_ptr)[0])
> +                                             return false;
> +
> +                                     s1_ptr += 2;
> +                                     s2_ptr += 2;
> +                                     len -= 2;
> +                             }
> +
> +                             return len == 0 || *s1_ptr == *s2_ptr;
>                       }
>               }
>  
> 
> 
> ------------------------------------------------------------------------
> 
> using System;
> 
> namespace ConsoleApplication1 {
> 
>       class Program {
>               static void Main(string[] args)
>               {
>                       string s1 = "original9";
>                       string yes = "original3";
>                       string s2 = "orig945";
>                       string yes2 = "orig943";
>                       string s3 = "original95";
>                       string yes3 = "original96";
>                       string s4 = "original_original_1";
>                       string yes4 = "original_original_0";
> 
>                       const int count = 100000000;
> 
>                       DateTime s = DateTime.Now;
>                       for (int i = 0; i < count; ++i) {
>                               String.Equals(s1, yes);
>                               String.Equals(s3,yes3);
>                               String.Equals(s2,yes2);
>                               String.Equals(s4,yes4);
>                               String.Equals("", "");
>                       }
> 
>                       Console.WriteLine(DateTime.Now - s);
>               }
>       }
> }


_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to