.NET深入学习笔记(2):C#中判断空字符串的4种方法性能比较与分析

作者:互联网   出处:控件中国网   2014-11-05 19:17:17   阅读:1

写的一篇关于字符串为空判断方法的性能分析文章,实验结果作者已经给出,结论是使用.length==0判断的效率最高,但是文章的结尾只有一句话,感觉不够详细,所以自己写下这个文章,算一个补充和学习吧.

程序代码执行的硬件环境:

CPU

Intel T2300 1.66GHz

内存

Kingston DDR2 667 1G

硬盘

80G 5400 8m

     测试的软件环境:

OS

Windows XP Pro

IDE

VS 2008 RTM

     测试的代码如下:

定义了3个变量,分别调用4种方法,进行100w次判断,记录测试时间:

 


  1Stopwatch sw = new Stopwatch();//实例化一个对象,记录时间
  2            string sEmpty1 = string.Empty;//实例化3个字符串对象,赋值如下。分别作空比较试验
  3            string sEmpty2 = "";
  4            string sEmpty3 = "StringNotEmpty";
  5            ////////////////////////////////////////////////////Test sEmpty1///////////////////////////
  6            sw.Start();//开始记录
  7            for (int i = 0; i <= 1000000; i++)
  8            {
  9                if (sEmpty1.Length == 0
 10                { }
 11            }

 12            sw.Stop();//停止记录时间
 13            Console.WriteLine("string.Empty Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
 14            ////////
 15            sw.Reset();//重置计数器为0;
 16            sw.Start();
 17            for (int i = 0; i <= 1000000; i++)
 18            {
 19                if (sEmpty1 == "")
 20                { }
 21            }

 22            sw.Stop();
 23
 24            Console.WriteLine("string.Empty == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
 25            ////
 26            sw.Reset();
 27            sw.Start();
 28            for (int i = 0; i <= 1000000; i++)
 29            {
 30                if (sEmpty1 == string.Empty) 
 31                { }
 32            }

 33            sw.Stop();
 34            Console.WriteLine("string.Empty  == string.Empty Time Cost is {0}", sw.ElapsedMilliseconds);
 35
 36            sw.Reset();
 37            sw.Start();
 38            for (int i = 0; i <= 1000000; i++)
 39            {
 40                if(string.IsNullOrEmpty(sEmpty1))
 41                {}
 42            }

 43            sw.Stop();
 44            Console.WriteLine("string.IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
 45            Console.WriteLine();
 46            ////////////////////////////////////////////////////Test sEmpty2///////////////////////////
 47            sw.Reset();
 48            sw.Start();
 49            for (int i = 0; i <= 1000000; i++)
 50            {
 51                if(sEmpty2.Length == 0)
 52                {}
 53            }

 54            sw.Stop();
 55            Console.WriteLine("\"\" Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
 56            ////////
 57            sw.Reset();
 58            sw.Start();
 59             for (int i = 0; i <= 1000000; i++)
 60            {
 61                if(sEmpty2 == "")
 62                {}
 63            }

 64            sw.Stop();
 65            Console.WriteLine("\"\" == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
 66            /////
 67            sw.Reset();
 68            sw.Start();
 69            for (int i = 0; i <= 1000000; i++)
 70            {
 71                if(sEmpty2 == string.Empty)
 72                {}
 73            }

 74            sw.Stop();
 75            Console.WriteLine("\"\"  == string.Empty Test3 Time Cost is {0}", sw.ElapsedMilliseconds);
 76            /////
 77            sw.Reset();
 78            sw.Start();
 79            for (int i = 0; i <= 1000000; i++)
 80            {
 81                if(string.IsNullOrEmpty(sEmpty2))
 82                {}
 83            }

 84            sw.Stop();
 85            Console.WriteLine("\"\" string.IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);
 86            Console.WriteLine();
 87            ////////////////////////////////////////////////////Test sEmpty3///////////////////////////
 88            sw.Reset();
 89            sw.Start();
 90            for (int i = 0; i <= 1000000; i++)
 91            {
 92                if(sEmpty3.Length == 0)
 93                {}
 94            }

 95            sw.Stop();
 96            Console.WriteLine("\"StringNotEmpty\" Length == 0 Time Cost is {0}", sw.ElapsedMilliseconds);
 97            ////////
 98            sw.Reset();
 99            sw.Start();
100            for (int i = 0; i <= 1000000; i++)
101            {
102                if(sEmpty3 == "")
103                {}
104            }

105            sw.Stop();
106            Console.WriteLine("\"StringNotEmpty\" == \"\" Time Cost is {0}", sw.ElapsedMilliseconds);
107            ////
108            sw.Reset();
109            sw.Start();
110            for (int i = 0; i <= 1000000; i++)
111            {
112                if(sEmpty3 == string.Empty)
113                {}
114            }

115            sw.Stop();
116            Console.WriteLine("\"StringNotEmpty\"  == string.Empty Test3 Time Cost is {0}", sw.ElapsedMilliseconds);
117            ////
118            sw.Reset();
119            sw.Start();
120            for (int i = 0; i <= 1000000; i++)
121            {
122                if(string.IsNullOrEmpty(sEmpty3))
123                {}
124            }

125            sw.Stop();
126            Console.WriteLine("\"StringNotEmpty\" IsNullOrEmpty Time Cost is {0}", sw.ElapsedMilliseconds);

 

 

 

结果分析来看,调用string的length==0作比较,不论字符串是否为空,此方法的效率最高,此点与清清月儿的结果一致;

string的isNullOrEmpty()方法的效率基本不变,无论字符串是否有值;

== string.Empty== ""两种方法在3个变量测试的实验中效率相对较低,但是两者再和对方比较的时候会出现效率降低的情况,见上图;

    原因是什么呢?我们来看看对应的il代码:

 


 1.locals init ([0class [System]System.Diagnostics.Stopwatch sw,
 2           [1string sEmpty1,
 3           [2string sEmpty2,
 4           [3string sEmpty3,
 5           [4] int32 i,
 6           [5bool 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
18

 

两者的差别由于推送到堆栈上的内容不同,前者是静态共享值推送到堆栈,后者是字符串对象的地址推送到堆栈.

造成的比较差别.另外字符串值是否相等的资料大家可以看看园子里缘清的文章,有很好的参考价值.希望大家一起交流!

谢谢!~(本文由转载) 控件中国网

Copyright© 2006-2015 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 渝ICP备12000264号 法律顾问:元炳律师事务所
客服软件
live chat