关于字符串为空的几个性能测试

今天突然有兴做了两下有关字符串为空的性能测试,与大家分享!结果如下:
两种赋值方式的比较:
string str="";
string str=string.Empty;
理论上讲:
string.Empty是一个Static的属性,使用时不分配存储空间,而在用""时,系统会分配一个长度为空的存储空间。不过编译系统应该会优化,也就是说,比如你程序中有10个地方用到了"",但好的编译系统应该引用的是同一个对象。所以用""也就是浪费一个对象空间而已。
实战:
测试程序如下:
namespace testEmpty
{
    class Program
    {
        static void Main(string[] args)
        {
            Test test = new Test();
            test.testEmpty();
            test.testEqualEmpty();
            Console.Read();
        }       
    }
    class Test
    {
        public void testEmpty()
        {
            string str;
            for (int i = 0; i < 10000; i++)
            {
                str = "";
            }
        }
        public void testEqualEmpty()
        {
            string str;
            for (int i = 0; i < 10000; i++)
            {
                str = string.Empty;
            }
        }
    }
}

 测试过程是分别将赋值语句str=""和str=string.Empty用两个函数执行10000次,所用时间如下所示:
    两个方法耗费时间表
所以说:单独执行testEmpty()执行10000次用了0.262669毫秒,单独执行testEqualEmpty()执行0.026849毫秒。前者是后者的10倍.

下面介绍的是几种判断语句的比较:
我想到的所有的判断空字符串的语句就这几种了,大家还有其它方法的欢迎讨论!
str == ""
str.Equals("")
str==string.Empty
str.Equals(string.Empty)
str .Length==0


测试程序如下:
using System;
using System.Collections.Generic;
using System.Text;

namespace testEmpty
{
    class Program
    {
        static void Main(string[] args)
        {
            Test test = new Test();
            test.test1();
            test.test2();
            test.test3();
            test.test4();
            test.test5();
            Console.Read();
        }       
    }
    class Test
    {
        string str = string.Empty;
        public void test1()
        {
            for (int i = 0; i < 10000; i++)
            {
                if (str == "")
                {
                    Console.WriteLine("1 This string is emput");
                }
            }
        }
        public void test2()
        {
            for (int i = 0; i < 10000; i++)
            {
                if (str.Equals(""))
                {
                    Console.WriteLine("2 This string is emput");
                }
            }
        }
        public void test3()
        {
            for (int i = 0; i < 10000; i++)
            {
                if (str==string.Empty)
                {
                    Console.WriteLine("3 This string is emput");
                }
            }
        }
        public void test4()
        {
            for (int i = 0; i < 10000; i++)
            {
                if (str.Equals(string.Empty))
                {
                    Console.WriteLine("4 This string is emput");
                }
            }
        }
        public void test5()
        {
            for (int i = 0; i < 10000; i++)
            {
                if (str .Length==0)
                {
                    Console.WriteLine("5 This string is emput");
                }
            }
        }
    }
}

在这个测试程序中,用了5个分别含有这5种判断语句的方法,目的就是为了测试每个方法耗费的时间。
在这里说明一下,笔者在这个程序中起的名字不可取,程序员不应该这样为方法起名字的,见笑了!
测试结果如下:
判断5种语句的测试结果
 呵呵,可以从这个方法耗费时间详细说明表中看出,这些方法耗费时间都比较,这主要是因为里面的Console.WriteLine()语句影响的。但是每个方法中都有这一语句,所以说它并不影响我们的比较结果!
得出的结论:在字符串为空时,这五种判断语句的耗费时间由短到长
str .Length==0
str.Equals("")
str==string.Empty
str.Equals(string.Empty)
str == ""
你平时有的哪种比较语句呢?呵呵……
需要说明的是:这只是在字符串为空时结果是这样的,那么字符串不为空时呢,结果又是怎样的呢?

©2007 renly
原创作品,欢迎转载,转载请注明出自博客园,留此信息!

Tag标签: 性能,字符串

posted on 2007-07-27 22:10 任力 阅读(2765) 评论(41)  编辑 收藏 所属分类: C、.NET Framework

评论

#1楼  2007-07-27 22:34 iaucd [未注册用户]

我刚开始做程序时用的是str.length==0
后来用的是str=="",这个比较顺手。
后来网上介绍说str==string.Empty 性能好,所以就用这个了,偶尔用一次str.Equals("")迷糊了这么长时间,今天终于懂了,呵呵
顶顶   回复  引用    

#2楼  2007-07-27 22:43 flyingchen      

10000次差距都这么小,基本没啥区别阿,不太懂更底层的原理(当然你也没有分析到),不过对这种精神,帮顶了   回复  引用  查看    

#3楼  2007-07-27 22:46 Jonny Yu      

常年使用string.IsNullOrEmpty()
不过老实说,我觉得string比较不会是性能瓶颈吧。   回复  引用  查看    

#4楼  2007-07-28 03:55 UFO [未注册用户]

常用 String.IsNullOrEmpty()   回复  引用    

#5楼  2007-07-28 07:22 万恶的验证码 [未注册用户]

就用string.IsNullOrEmpty了,LZ给的五种方法从来不都用   回复  引用    

#6楼  2007-07-28 07:55 黑土 [未注册用户]

大家都是来交流的嘛!感谢LZ的实验数据!学习了!   回复  引用    

#7楼  2007-07-28 08:33 zoti      

有理論支持嗎?不清楚為何String.Empty會比""慢,呵呵。
關注中。   回复  引用  查看    

#8楼  2007-07-28 08:42 Bruce Lee      

测试表格是自动生成的还是自己画的?   回复  引用  查看    

#9楼  2007-07-28 08:42 绿蚂蚁      

一直用String.IsNullOrEmpty()   回复  引用  查看    

#10楼  2007-07-28 08:46 任力 [未注册用户]

@zoti
不是string.Empty比""慢,而是比""快!
理论支持:
string.Empty是一个Static的属性,在.NET Framework中有它的值,使用时不分配存储空间,而在用""时,系统会把它当作一个字符串来处理,会分配一个长度的存储空间,只不过在这个存储空间上的值是空而已!
  回复  引用    

#11楼  2007-07-28 09:00 任力 [未注册用户]

@Bruce Lee 测试表格是自动生成的还是自己画的?
Visual Studio 2005中有这种工具,工具菜单下的“性能工具”,试一下,代码测试中的代码瓶颈,都可以用它来找到!
  回复  引用    

#12楼  2007-07-28 09:01 三千.℡      

差距很小.
  回复  引用  查看    

#13楼  2007-07-28 09:32 progame      

if (str.Equals(""))
{
Console.WriteLine("2 This string is emput");
}

你这个时间都console.writeline用掉了   回复  引用  查看    

#14楼 [楼主] 2007-07-28 09:34 任力      

@progame
是的,大部分都被它占去了,但是并不会影响比较的结果!   回复  引用  查看    

#15楼  2007-07-28 09:43 teracy_cai      

支持博主,性能优化要从点滴做起,以后要多做做这样的性能比较,得到我们想要的最佳使用方法....3Q   回复  引用  查看    

#16楼  2007-07-28 09:47 progame      

关于第一个测试, 你反编译的EXE就知道了, 两个方法里的赋值全部被优化掉了

关于第二个测试 不要使用Console.WriteLine来干扰测试结果   回复  引用  查看    

#17楼  2007-07-28 09:47 progame      

namespace testEmpty
{
class Program
{
static void Main(string[] args)
{
Test test = new Test();
for (int i = 0; i < 5; i++)
{
DateTime dt = DateTime.Now;
test.testEmpty();
TimeSpan ts = DateTime.Now - dt;
Console.Write("empty {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
test.testEqualEmpty();
ts = DateTime.Now - dt;
Console.Write(" string.empty {0}", ts.TotalMilliseconds);
Console.Write("\r\n");
}
Console.Read();
}
}
class Test
{
public void testEmpty()
{
string s= "abc";

for (int i = 0; i < 100000000; i++)
{
s = "";
}
int x = s.Length;
}
public void testEqualEmpty()
{
string str= "abc";
for (int i = 0; i < 100000000; i++)
{
str = string.Empty;
}
int x = str.Length;
}
}
}

结果:
empty 156.23 string.empty 109.361
empty 140.607 string.empty 109.361
empty 156.23 string.empty 109.361
empty 156.23 string.empty 109.361
empty 140.607 string.empty 109.361   回复  引用  查看    

#18楼  2007-07-28 09:53 progame      

using System;
using System.Collections.Generic;
using System.Text;

namespace testEmpty
{
class Program
{
static void Main(string[] args)
{
Test test = new Test();
for (int i = 0; i < 5; i++)
{
DateTime dt = DateTime.Now;
test.test1();
TimeSpan ts = DateTime.Now - dt;
Console.Write("test1 {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
test.test2();
ts = DateTime.Now - dt;
Console.Write("test2 {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
test.test3();
ts = DateTime.Now - dt;
Console.Write("test3 {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
test.test4();
ts = DateTime.Now - dt;
Console.Write("test4 {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
test.test5();
ts = DateTime.Now - dt;
Console.Write("test5 {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
test.test6();
ts = DateTime.Now - dt;
Console.Write("test6 {0} ", ts.TotalMilliseconds);
dt = DateTime.Now;
Console.Write("\r\n");
}
Console.Read();
}
}
class Test
{
string str = string.Empty;
public void test1()
{
for (int i = 0; i < 10000000; i++)
{
if (str == "")
{
i = i;
}
}
}
public void test2()
{
for (int i = 0; i < 10000000; i++)
{
if (str.Equals(""))
{
i = i;
}
}
}
public void test3()
{
for (int i = 0; i < 10000000; i++)
{
if (str == string.Empty)
{
i = i;
}
}
}
public void test4()
{
for (int i = 0; i < 10000000; i++)
{
if (str.Equals(string.Empty))
{
i = i;
}
}
}
public void test5()
{
for (int i = 0; i < 10000000; i++)
{
if (str.Length == 0)
{
i = i;
}
}
}
public void test6()
{
for (int i = 0; i < 10000000; i++)
{
if (string.IsNullOrEmpty(str))
{
i = i;
}
}
}
}
}

结果:
test1 140.607 test2 124.984 test3 46.869 test4 124.984 test5 15.623 test6 46.869

test1 156.23 test2 124.984 test3 46.869 test4 124.984 test5 31.246 test6 46.869

test1 140.607 test2 124.984 test3 62.492 test4 124.984 test5 15.623 test6 46.869

test1 156.23 test2 124.984 test3 46.869 test4 124.984 test5 15.623 test6 62.492

test1 140.607 test2 124.984 test3 46.869 test4 124.984 test5 31.246 test6 46.869

  回复  引用  查看    

#19楼  2007-07-28 09:54 镜涛      

呵呵,时间上的差距是在执行不同的方法语句时产生的。不过感觉差距还是比较小,我也是用string.IsNullOrEmpty()!
  回复  引用  查看    

#20楼 [楼主] 2007-07-28 10:02 任力      

@progame
谢谢你的加强版,学习了!   回复  引用  查看    

#21楼 [楼主] 2007-07-28 10:14 任力      

再次感谢progame,
请问一下:你在第一个测试中每个方法里面都有一句
int x = s.Length; 有什么用途?在线等!
  回复  引用  查看    

#22楼  2007-07-28 10:26 progame      

如果不加的话 那段循环里的同赋值会被优化掉的 你可以用reflector查看一下exe   回复  引用  查看    

#23楼 [楼主] 2007-07-28 11:04 任力      

@progame
是的!我看过了,谢谢了!又学习的一招!
不过,我现在又有问题了,不知是我的机器问题,还是其它原因…
我把你的第一个测试代码运行一下,结果显示:
empty 390.625 string.empty 390.625
empty 343.75 string.empty 375
empty 296.875 string.empty 375
empty 296.875 string.empty 375
empty 437.5 string.empty 453.125
结果与预计的相反!why?


  回复  引用  查看    

#24楼  2007-07-28 11:10 progame      

在release下运行

我把次数再放大了10倍 结果如下:
empty 1578.0341 string.empty 1093.687
empty 1562.41 string.empty 1093.687
empty 1562.41 string.empty 1078.0629
empty 1562.41 string.empty 1093.687
empty 1562.41 string.empty 1078.0629
  回复  引用  查看    

#25楼  2007-07-28 11:11 progame      

这是debug下的结果:
empty 2749.8768 string.empty 2718.6282
empty 2796.7497 string.empty 2687.3796
empty 2734.2525 string.empty 2687.3796
empty 2718.6282 string.empty 2671.7553
empty 2703.0039 string.empty 2671.7553


  回复  引用  查看    

#26楼  2007-07-28 11:14 tina [未注册用户]

职位名称: .net程序员
更新日期: 2007-7-28
公司名称: 创微科技有限公司
招聘部门: 系统开发部
工作地点: 广东 佛山
招聘人数: 1
学历要求: 大专
工作经验要求: 一年
工作类别: 全职
工资待遇: 2000-6000 其他待遇: 加班费+项目奖金+其他福利待遇(公司包住宿)
要求外语1: 英语 水平: 良好
联系电话: 0757-82360536
联系人: 耿小姐
使用语言或工具标签: ..net C# sqlserver2000
开发方向或服务行业标签: 网站开发 前后台处理 测试

职位描述:
1、熟练掌握ASP.NET(C#)、SQLServer2000数据库的设置和使用;熟悉WEB开发工具,熟悉javascript脚本编写。
2、熟悉B/S架构程序设计,具有优秀的系统设计、架构设计及开发能力。
3、熟悉网站架构程序设计及开发能力,能独立承担Web应用系统设计与开发工作。
4、能够熟练应用ASP.net进行大、中型门户型网站的开发经验一年以上(以下者勿扰),具有游戏开发相关工作经验者优先。

联系方式:
Email: qmodern@163.com
注:请在邮件中注明应聘职位的名称。   回复  引用    

#27楼  2007-07-28 14:01 Anders Cui      

用string.IsNullOrEmpty应该不太好吧
这里比较的是字符串为空
我最常用的还是Length   回复  引用  查看    

#28楼  2007-07-28 17:14 i.Posei      

你这测试性能的工具是什么?   回复  引用  查看    

#29楼 [楼主] 2007-07-28 17:46 任力      

上面不是提到了吗?
Visual Studio 2005中有这种工具,工具菜单下的“性能工具”,试一下,代码测试中的代码瓶颈,都可以用它来找到!   回复  引用  查看    

#30楼  2007-07-28 18:04 带头大哥 [未注册用户]

工具菜单下的“性能工具”

我怎么没有找到这个工具   回复  引用    

#31楼  2007-07-28 19:23 liu [未注册用户]

你好.能说说你用的什么性能测试工具呀?
能给介绍一下嘛!
谢谢!   回复  引用    

#32楼  2007-07-29 05:24 ho [未注册用户]

看不懂。。。努力啊!   回复  引用    

#33楼 [楼主] 2007-07-29 08:38 任力      

我是看了金旭亮新新编的那本书《.NET 2.0面向对象编程揭秘》才了解到的,
大家没用的可以看一下,上面介绍的很详细:
http://book.csdn.net/bookfiles/404/10040414781.shtml   回复  引用  查看    

#34楼  2007-07-29 09:16 progame      

楼主装的VS应该是TS版的 我原来装过 好像都带profiler和unit test的, pro版的没有 不过大家可以试试这个:
http://www.heybrain.com/progame/article/931.html   回复  引用  查看    

#35楼  2007-07-29 10:59 Da.Feng [未注册用户]

俺认为你的第一个测试有缺陷。
应该是:
string [] str;
for(int i=0;i<10000;i++)
{
str[i]=... ...
}
不是一个对象的赋值   回复  引用    

#36楼 [楼主] 2007-08-04 15:59 任力      

@Da.Feng
你好!应该是吧,我是刚接触这一块,做一个测试来与大家分享!
我们在这个讨论中共同提高,共同进步!
整个过程确实是对一个对象进行重新赋值,这样会不会影响测试的结果?
我再测试一下,也希望有人指出这个问题的理论依据!在此,谢谢大家   回复  引用  查看    

#37楼  2007-08-06 22:00 明海      

不错,谢谢你 ,让我提到了怎么把程序写好 虽然这个不能说明什么问题 ,但是对我来讲 有很大的感化   回复  引用  查看    

#38楼  2008-01-25 18:48 hoodlum1980      

这种比较意义确实较小,就第一种来说,当然我倾向于使用string.empty。
第二种来说,就我感觉来说,string.length<=0的性能给人的心理感觉上可能更舒服点。但是string.length要求string不能是null。否则将会出null引用异常。因此第二种情况更多都是用string.isnullorempty来做测试。

还有就是如果lz做string的+和stringbuilder的性能测试会更有价值一些,因为一般string少的时候就用+号了,太多字符串链接操作,或者是组装字符串时用stringbuilder。   回复  引用  查看    

#39楼 [楼主] 2008-01-25 20:48 任力      

@hoodlum1980
呵呵。。谢谢指导。当时可能水平有限吧,所以就没有做。
至于你说的string不能是null,是的,null会引出导常。

+与stringBuilder区别网上已有很多了,回去研究一下   回复  引用  查看    

#40楼  2008-03-22 12:49 Csea Xia      

@任力
那个性能测试怎么完啊。找到了,但是不会诶。   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-01-31 12:12 编辑过


相关链接:
 


导航

公告

IT新闻:

WCF揭秘

——微软WCF研发团队智慧结晶

ASP.NET AJAX实战

——ASP.NET之父强烈推荐

精通CSS与HTML设计模式

——CSS与HTML设计模式巅峰之作

立立很强悍! 10-6 14:46
<2007年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

统计

与我联系

搜索

 

常用链接

我参与的团队

随笔分类(24)

新闻分类(148)

相册

收藏夹(12)

DataBase

Friend

Web标准

外语偶像

最新随笔

最新评论

阅读排行榜

评论排行榜