c# - What is causing this implementation of GetHashCode to be 20 times slower than .net's implementation? -


i got idea of substring struct this post , this one. second post has implementation of .net's string.gethashcode(). (i'm not sure version of .net from.)

here implementation. (gethashcode taken second source listed above.)

public struct substring {     private string string;     private int offset;     public int length { get; private set; }     public char this[int index] { { return string[offset + index]; } }      public substring(string str, int offset, int len) : this()     {         string = str;         offset = offset;         length = len;     }      /// <summary>     /// see http://www.dotnetperls.com/gethashcode     /// </summary>     /// <returns></returns>     public unsafe override int gethashcode()     {         fixed (char* str = string + offset)         {             char* chptr = str;             int num = 352654597;             int num2 = num;             int* numptr = (int*)chptr;             (int = length; > 0; -= 4)             {                 num = (((num << 5) + num) + (num >> 27)) ^ numptr[0];                 if (i <= 2)                 {                     break;                 }                 num2 = (((num2 << 5) + num2) + (num2 >> 27)) ^ numptr[1];                 numptr += 2;             }             return (num + (num2 * 1566083941));         }     } } 

here's unit test:

    [test]     public void gethashcode_isasfastasstring()     {         var s = "the quick brown fox";         var sub = new substring(s, 1, 5);         var t = "quick";         var sum = 0;          sum += sub.gethashcode(); // make sure gethashcode jitted           var count = 100000000;         var sw = stopwatch.startnew();         (var = 0; < count; ++i)             sum += t.gethashcode();         var t1 = sw.elapsed;         sw = stopwatch.startnew();         (var = 0; < count; ++i)             sum += sub.gethashcode();         var t2 = sw.elapsed;          debug.writeline(sum.tostring()); // make sure use return value         var m1 = t1.milliseconds;         var m2 = t2.milliseconds;         assert.istrue(m2 <= m1); // fat chance     } 

the problem m1 10 milliseconds , m2 190 milliseconds. (note: 1000000 iterations.) fyi, ran on .net 4.5 64 bit release build optimizations turned on.

  1. clued comment, double checked make sure optimized code running. turns out obscure debugger setting disabling optimizations. unchecked tools – options – debugging – general – suppress jit optimization on module load (managed only). caused optimized code load properly.
  2. even optimizations turned on there still 3x - 6x difference. however, might attributable fact code above .net 32 bit version , i'm running 64 bit .net. porting 64 bit implementation of string.gethashcode substring not easy because relies on 0 end of string marker (which in fact bug).

at time i'm disappointed not getting parity performance, excellent use of time in learning of perils , pitfalls of optimizing c#.


Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

visual studio 2010 - Connect to informix database windows form application -

android - Associate same looper with different threads -