近来重新翻看dotnet程序框架设计,看讲到字符串驻留时,说C#编译器使用了IsInterned方法对switch/case语句进行了性能优化,并给出了一个例子,例子后也给出了IL代码,其中性能优化部分是这样的:
call string [mscorlib]System.String::IsInterned(string)
|
为了检验是否如此,我写了一个简单的代码,生成IL代码后,却发现并非如此.也许是写的代码哪里不对,阻碍了switch/case以IsInterned进行性能优化.我又按照书上的代码重写程序,并生成IL代码,但结果显示,仍然没有使用IsInterned进行优化,而使用的IL代码为:
call bool [mscorlib]System.String::op_Equality(string,string)
|
op_Equality方法确定两个指的String对象是否具有同一值,使用Equals算法实现此运算符.也就是说它仍然是在比较String对象中的每一个字符,而这种方法的效率是比较低的.
使用IsInterned方法是利用字符串驻留技术,它比较驻留在进程中散列表内的字符串的引用,如果没有,则返回null,有则返回该字符串引用, 效率非常高.当CLR初始化时,它会将进程中的文本常量字符串加入内部散列表中.如果字符串对象是由变量组合而成,则不会加入散列表.但可以使用Intern方法加入.它首先会寻找散列中是否已经存在该字符串,如果有则返回该引用,如果没有加入散列表,并返回该引用.这样大大减少了内存的使用,提高了字符串对象的比较效率.
该书中所讲使用IsInterned方法优化switch,但却并非如此.
阅读(1329) | 评论(0) | 转发(0) |