(3)用relector看Hashtable源代码,消除无用操作,继续优化
还能不能继续优化呢?ConvertChar (char input)执行次数最多,是对性能最有影响的方法。用reflector反编译Hashtable的get_Item(object key)方法:
1 public virtual object get_Item(object key) 2 { 3 uint num1; 4 uint num2; 5 Hashtable.bucket bucket1; 6 if (key == null) 7 { 8 throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); 9 } 10 Hashtable.bucket[] bucketArray1 = this.buckets; 11 uint num3 = this.InitHash(key, bucketArray1.Length, out num1, out num2); 12 int num4 = 0; 13 int num5 = (int) (num1 % bucketArray1.Length); 14 do 15 { 16 bucket1 = bucketArray1[num5]; 17 if (bucket1.key == null) 18 { 19 return null; 20 } 21 if (((bucket1.hash_coll & 0x7fffffff) == num3) && this.KeyEquals(key, bucket1.key)) 22 { 23 return bucket1.val; 24 } 25 num5 = (int) ((num5 + num2) % ((ulong) bucketArray1.Length)); 26 } 27 while ((bucket1.hash_coll < 0) && (++num4 < bucketArray1.Length)); 28 return null; 29 } |
我的天天天天天天天天天天天天天........好长呀,先不管这个。哦,方法并不抛出异常,如果key不存在就直接返回null。这样的话,采用ContainsKey(...)判断key是否存在就是多次一举了。
把ConvertChar (char input)改为:
1 private static char ConvertChar(char input) 2 { 3 object temp = _libTable[input]; 4 return temp == null?input:(char)temp; 5 } |
这样大概能节省一半的操作。
测试结果验证了我这一想法。性能一下提高了40%,达到了500万字/s
注:上面程序有小bug,后来发现的。