偶然看到<C#中判断空字符串的3种方法性能分析 >作者:清清月儿 主页:http://blog.csdn.net/21aspnet/ 时间:2007.4.28
写的一篇关于字符串为空判断方法的性能分析文章,实验结果作者已经给出,结论是使用.length==0判断的效率最高,但是文章的结尾只有一句话,感觉不够详细,所以自己写下这个文章,算一个补充和学习吧。
【1】
程序代码执行的硬件环境:
CPU
|
Intel T2300 1.66GHz
|
内存
|
Kingston
DDR2 667 1G
|
硬盘
|
80G
5400
转
8m
|
测试的软件环境:
OS
|
Windows XP Pro
|
IDE
|
VS 2008 RTM
|
【2】测试的代码如下:
定义了3个变量,分别调用4种方法,进行100w次判断,记录测试时间:
Stopwatch sw =
new Stopwatch();
//实例化一个对象,记录时间
string sEmpty1 = string.Empty; //实例化3个字符串对象,赋值如下。分别作空比较试验
string sEmpty2 = "";
string sEmpty3 = "StringNotEmpty";
////////////////////////////////////////////////////Test sEmpty1///////////////////////////
sw.Start(); //开始记录
for ( int i = 0; i <= 1000000; i++)
{
if (sEmpty1.Length == 0)
{ }
}
sw.Stop(); //停止记录时间
Console.WriteLine( "string.Empty Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
////////
sw.Reset(); //重置计数器为0;
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if (sEmpty1 == "")
{ }
}
sw.Stop();
Console.WriteLine( "string.Empty == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if (sEmpty1 == string.Empty)
{ }
}
sw.Stop();
Console.WriteLine( "string.Empty == string.Empty Time Cost is {0}", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if( string.IsNullOrEmpty(sEmpty1))
{}
}
sw.Stop();
Console.WriteLine( "string.IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
Console.WriteLine();
////////////////////////////////////////////////////Test sEmpty2///////////////////////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty2.Length == 0)
{}
}
sw.Stop();
Console.WriteLine( "\"\" Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty2 == "")
{}
}
sw.Stop();
Console.WriteLine( "\"\" == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
/////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty2 == string.Empty)
{}
}
sw.Stop();
Console.WriteLine( "\"\" == string.Empty Test3 Time Cost is {0}", sw.ElapsedMilliseconds);
/////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if( string.IsNullOrEmpty(sEmpty2))
{}
}
sw.Stop();
Console.WriteLine( "\"\" string.IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
Console.WriteLine();
////////////////////////////////////////////////////Test sEmpty3///////////////////////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty3.Length == 0)
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty3 == "")
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty3 == string.Empty)
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" == string.Empty Test3 Time Cost is {0}", sw.ElapsedMilliseconds);
////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if( string.IsNullOrEmpty(sEmpty3))
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
string sEmpty1 = string.Empty; //实例化3个字符串对象,赋值如下。分别作空比较试验
string sEmpty2 = "";
string sEmpty3 = "StringNotEmpty";
////////////////////////////////////////////////////Test sEmpty1///////////////////////////
sw.Start(); //开始记录
for ( int i = 0; i <= 1000000; i++)
{
if (sEmpty1.Length == 0)
{ }
}
sw.Stop(); //停止记录时间
Console.WriteLine( "string.Empty Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
////////
sw.Reset(); //重置计数器为0;
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if (sEmpty1 == "")
{ }
}
sw.Stop();
Console.WriteLine( "string.Empty == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if (sEmpty1 == string.Empty)
{ }
}
sw.Stop();
Console.WriteLine( "string.Empty == string.Empty Time Cost is {0}", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if( string.IsNullOrEmpty(sEmpty1))
{}
}
sw.Stop();
Console.WriteLine( "string.IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
Console.WriteLine();
////////////////////////////////////////////////////Test sEmpty2///////////////////////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty2.Length == 0)
{}
}
sw.Stop();
Console.WriteLine( "\"\" Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty2 == "")
{}
}
sw.Stop();
Console.WriteLine( "\"\" == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
/////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty2 == string.Empty)
{}
}
sw.Stop();
Console.WriteLine( "\"\" == string.Empty Test3 Time Cost is {0}", sw.ElapsedMilliseconds);
/////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if( string.IsNullOrEmpty(sEmpty2))
{}
}
sw.Stop();
Console.WriteLine( "\"\" string.IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
Console.WriteLine();
////////////////////////////////////////////////////Test sEmpty3///////////////////////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty3.Length == 0)
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
////////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty3 == "")
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if(sEmpty3 == string.Empty)
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" == string.Empty Test3 Time Cost is {0}", sw.ElapsedMilliseconds);
////
sw.Reset();
sw.Start();
for ( int i = 0; i <= 1000000; i++)
{
if( string.IsNullOrEmpty(sEmpty3))
{}
}
sw.Stop();
Console.WriteLine( "\"StringNotEmpty\" IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
代码的运行结果如下:
结果分析来看,调用string的length==0作比较,不论字符串是否为空,此方法的效率最高,此点与清清月儿的结果一致;
string的isNullOrEmpty()方法的效率基本不变,无论字符串是否有值;
== string.Empty和
== ""两种方法在3个变量测试的实验中效率相对较低,但是两者再和对方比较的时候会出现效率降低的情况,见上图;
【3】原因剖析:
原因是什么呢?我们来看看对应的il代码:
1.locals init ([0]
class [System]System.Diagnostics.Stopwatch sw,
2 [1] string sEmpty1,
3 [2] string sEmpty2,
4 [3] string sEmpty3,
5 [4] int32 i,
6 [5] bool CS$4$0000)
7 IL_0000: nop
8 IL_0001: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
9 IL_0006: stloc.0
10 IL_0007: ldsfld string [mscorlib]System.String::Empty //将指定字段的值推送到堆栈上。 ldsfld 指令将静态(在类的所有实例中共享)字段的值推送到堆栈上。返回类型是与传递的元数据标记 field 关联的类型。
11
12 IL_000c: stloc.1
13 IL_000d: ldstr "" //将对字符串的对象引用推送到堆栈上,ldstr 指令推送对表示在元数据中存储的特定字符串的新字符串对象的对象引用(O 类型)。
14 IL_0012: stloc.2
15 IL_0013: ldstr "StringNotEmpty" //将对字符串的对象引用推送到堆栈上,ldstr 指令推送对表示在元数据中存储的特定字符串的新字符串对象的对象引用(O 类型)。
16 IL_0018: stloc.3
17 IL_0019: ldloc.0
2 [1] string sEmpty1,
3 [2] string sEmpty2,
4 [3] string sEmpty3,
5 [4] int32 i,
6 [5] bool CS$4$0000)
7 IL_0000: nop
8 IL_0001: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
9 IL_0006: stloc.0
10 IL_0007: ldsfld string [mscorlib]System.String::Empty //将指定字段的值推送到堆栈上。 ldsfld 指令将静态(在类的所有实例中共享)字段的值推送到堆栈上。返回类型是与传递的元数据标记 field 关联的类型。
11
12 IL_000c: stloc.1
13 IL_000d: ldstr "" //将对字符串的对象引用推送到堆栈上,ldstr 指令推送对表示在元数据中存储的特定字符串的新字符串对象的对象引用(O 类型)。
14 IL_0012: stloc.2
15 IL_0013: ldstr "StringNotEmpty" //将对字符串的对象引用推送到堆栈上,ldstr 指令推送对表示在元数据中存储的特定字符串的新字符串对象的对象引用(O 类型)。
16 IL_0018: stloc.3
17 IL_0019: ldloc.0
两者的差别由于推送到堆栈上的内容不同,前者是静态共享值推送到堆栈,后者是字符串对象的地址推送到堆栈.
造成的比较差别.另外字符串值是否相等的资料大家可以看看园子里缘清的文章,有很好的参考价值.地址:
http://www.cnblogs.com/isline/archive/2009/02/04/1383799.html.希望大家一起交流!
谢谢!~
本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/318543,如需转载请自行联系原作者