两种不同字符串比较方法的性能对比
2007-08-17 01:01
711 查看
最近比较关注C#书写出来的代码性能问题,越研究就越觉得很有意思。
在日常的编程过程总,由于编程需要,我们经常会比较两个字符串是否相等,然后再做相应的处理。代码书写起来是觉得很爽,不是吗?if (a==b) then ……else……但是有没有更快的方式呢?为此查阅了一些资料了MSDN文档。当我们调用 a==b的时候,通过IL代码可以看到内部实际上调用了String.Equals(string,string)这个方法
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
IL_0021: call bool [mscorlib]System.String::op_Equality(string,
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
string)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
IL_0026: stloc.s re
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public static bool Equals(string a, string b)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (a == b)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return true;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if ((a != null) && (b != null))
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return EqualsHelper(a, b);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return false;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
更为严重的是更底层调用的是EqualsHelper辅助方法,它首先比较两个字符串的长度,然后逐个字符的通过引用指针的方式进行比较,由于无法明确的区隔是否和语言别有关系,内部处理异常复杂。有没有更快速的方法呢?
答案是有的。
.Net 2.0中新增了一个StringComparison枚举类型,实际上我们大多数的字符串比较是和语言别无关的,我们应该使用Ordinal和OrdinalIgnoreCase两个枚举值。处于性能考虑,在字符串比较时不应该直接使用==操作符,而应该使用
bool Equals(string value, StringComparison comparisonType)
bool Equals(string a, string b, StringComparison comparisonType)
为此,我进行了一个测试,看看不等的==操作符和String.Equals方法之间的性能差别有多大。
测试代码:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
string a = "abcdefghigklmnopqrstuvwxyz0123456789!@#$%^&*()_+";
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
string b = "abcdefghigklmnopqrstuvwxyz0123456789!@#$%^&*()_+?";
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Stopwatch watch = new Stopwatch();
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
watch.Start();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
for (int i = 0; i < 90000000; i++)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
bool re = a.Equals(b, StringComparison.OrdinalIgnoreCase);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
watch.Stop();
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
double time = watch.Elapsed.TotalSeconds;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Console.Write(time);
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Console.ReadLine();
测试了三次,分别为:1.1163117,1.106148,1.1041815
然后运行下面的代码:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
string a = "abcdefghigklmnopqrstuvwxyz0123456789!@#$%^&*()_+";
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
string b = "abcdefghigklmnopqrstuvwxyz0123456789!@#$%^&*()_+?";
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Stopwatch watch = new Stopwatch();
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
watch.Start();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
for (int i = 0; i < 90000000; i++)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
bool re = (a == b);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
watch.Stop();
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
double time = watch.Elapsed.TotalSeconds;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Console.Write(time);
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Console.ReadLine();
测试了三次,分别为:1.6392576,1.6143791,1.6253847
算出平均值之后,两者在速度上相差46.675%。
呵呵,差别惊人阿!
相关文章推荐
- 再谈两种不同字符串比较方法的性能对比
- 两种不同字符串比较方法的性能对比
- 比较两个字符串空,两种方法性能比较
- 在输入的字符串中判断是否有a,多种方法(比较前两种不同的表示方法)
- 五种不同的 URL 参数解析方法的性能比较
- 从字符串中查找字符出现次数的方法和性能对比
- java中subString、split、stringTokenizer三种截取字符串方法的性能比较
- 判断一个字符串是否全是数字的多种方法及其性能比较(C#实现)
- 五种不同的 URL 参数解析方法的性能比较
- 五种不同的 URL 参数解析方法的性能比较
- apache日志的不同统计方法性能比较
- 判断一个字符串是否全是数字的多种方法及其性能比较(C#实现)
- 不同版本的SQL Server之间数据导出导入的方法及性能比较
- String类的split()方法与StringTokenizer方法对字符串分割并输出内容的性能比较
- 几种获得中英文混合字符串长度方法的性能比较
- 自定义字符串处理函数(求长度,拷贝、拼接、比较)--两种方法
- java java中subString、split、stringTokenizer三种截取字符串方法的性能比较
- Sql Server中三种字符串合并方法的性能比较
- 从字符串中查找字符出现次数的方法和性能对比
- java中subString、split、stringTokenizer三种截取字符串方法的性能比较