C# 字符串性能

Written By Dr Herbie [2]

Translated By Allen Lee


Introduction

你在代码中处理字符串的方法可能会对性能产生令人吃惊的影响。程序中需要考虑两个由于使用字符串而产生的问题:临时字符串变量的使用和字符串连接。
Background
1.String是引用类型,在堆上分配内存。

2.String运算时会产生一个新的实例。当看到 myString.ToUpper() 时,我经常都会忘记它并不是改变 myString 的内容而是返回一整个全新的字符串(这是由于 C# 中字符串是不可变的)。

3.String 对象一旦生成不可改变(Immutable)。

4.定义相等运算符(== 和 !=)是为了比较 String 对象(而不是引用)的值。

String Comparison and Temporary String Creation

下面的例程是一个蹩脚的非大小写敏感的字符串比较。用于比较的例程的代码是:

 

static bool BadCompare(string stringA, string stringB)
ExpandedBlockStart.gifContractedBlock.gif
{
    
return (stringA.ToUpper() == stringB.ToUpper());
}

 

对于这段代码,FxCop 给出如下的建议:

 

"StringCompareTest.BadCompare(String, String):Boolean calls String.op_Equality(String, String):Boolean after converting 'stack1', a local, to upper or lowercase. If possible, eliminate the string creation and call the overload of String.Compare that performs a case-insensitive comparison."

 

这项建议的意思是每次对 ToUpper() 的调用都会创造一个临时字符串,而这个临时字符串是由垃圾收集器来创建和管理的。这需要额外的时间和使用更多的内存。 String.Compare 方法(相对来说)更加高效。

String Concatenation inside a loop

最后那对测试例程设想字符串的连接是在一个循环里面进行的。

“蹩脚”的测试例程的代码如下:

 

static string BadConcatenate(string [] items)
ExpandedBlockStart.gifContractedBlock.gif
{
    
string strRet = string .Empty;

    
foreach (string item in items)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        strRet += item;
    }


    
return strRet;
}

 

当 FxCop 看到这段代码,它就会很愤怒,甚至用红色标记这项被破的规条! FxCop 这样说道:

 

"Change StringCompareTest.BadConcatenate(String[]):String to use StringBuilder instead of String.Concat or +="

 

“优良”的测试例程的代码如下:

 

static string GoodConcatenate(string [] items)
ExpandedBlockStart.gifContractedBlock.gif
{
    System.Text.StringBuilder builder = 
new System.Text.StringBuilder();

    
foreach (string item in items)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        builder.Append(item);
    }


    
return builder.ToString();
}

 

这段代码几乎被用作展示 System.Text.StringBuilder 的用法的首选例子。蹩脚的代码的问题是创建了过多的临时字符串。由于字符串的不可变特性,连接操作符(+=)实际上用原来那两个字符串来创建一个新的字符串,然后把原来的字符串实例指向这个新的字符串。

但是,依据 nprof 来研究代码性能,我们发现运行 BadConcatenate 只需总执行时间的 5.67% ,而 GoodConcatenate 则是 22.09% 。也就是说:

使用 StringBuilder 耗费的时间几乎是简单的字符串连接的四倍!

为什么呢?

部分原因在于这个测试的设计——连接例程仅仅连接了十个简短的字符串。 StringBuilder 是一个比简单的不可变的字符串类更复杂的类,因此创建一个 StringBuilder 比起进行十个简单的字符串连接在性能上是昂贵很多的。

我重复地做不同数目的字符串连接的测试,并且发现以下结果:

Chart of concatenation method effect on relative performance.

 

Conclusions

使用 String.Compare 方法进行非大小写敏感的字符串比较。这样更快。而且代码优雅和简单。

仅当你在一个循环里进行超过 600 次的字符串连接时,使用 StringBuilder 来获得更好的速度。这里需要提醒的是,你所处理的字符串的长度也会影响最终的速度,同样会影响垃圾收集器的效果,所以你应该根据你实际的代码具体问题具体分析

 

使用 StringBuilder 来处理字符串的连接应该是绝大多数 .NET 开发人员的共识了。但你有否曾经怀疑过这一经验原则的适用性是否真如想象中那么广泛呢?读过本文后,或许你已经意识到这是个适度的问题。对小规模的字符串连接使用 StringBuilder 所带来的改善根本不足以抵偿因 StringBuilder 本身的复杂性所产生的开销;只有当连接规模达到临界规模,两者才能相互抵偿从而达至平衡。

 

 

转载于:https://www.cnblogs.com/lotussoft/archive/2009/08/25/1553941.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手把手教你部署VSAN见证虚拟设备 (Cormac)

译者注:本文翻译自Cormac的博客,并未严格地逐字逐句的直译,如有谬误,万望见谅。原文见此http://cormachogan.com/2015/09/14/step-by-step-deployment-of-the-vsan-witness-appliance/现在开始在之前的帖子中我曾经介绍过见证虚拟…

PyCharm编程环境的中英文字体分别设置的好处多----一石三鸟地解决中文字体不一致、英文字体不涵盖中文字符、编程字体实用性兼顾美观性的三个问题

在编程环境(例如Python的PyCharm)中,我们希望编程环境的字体具有如下特性: (1)字体覆盖中文和英文字符。 (2)等宽字体,并且是TrueType字体,方便辨识代码中缩…

WordPress博客系统的安全

随着计算机网络的流行,越来越多的人开始创建自己的博客,论起博客系统,全球用的最多的博客系统就是wordpress(以下简称WP)。但是如果用过WP的人都应该知道,WP的站点想要做的好看,插件是必不可少的…

mysql为什么行数据库_关系数据表中的行称为什么?

在一个二维表中,水平方向的行称为元组,每一行是一个元组;元组对应表中的一个具体记录。数据元组也称为记录。一个数据表中的每一个记录均有一个惟一的编号(记录号)。一个记录也就是数据表中的一行。元组(tuple)是关系数据库中的基本概念&…

maven安装以及eclipse配置maven

http://jingyan.baidu.com/article/295430f136e8e00c7e0050b9.html 必须先下载并安装JDK,配置JDK的环境变量JAVA_HOME,否则maven将无法使用 eclipse安装maven插件后必须重新定位maven到本地maven目录 如下定位: 为了使得Eclipse中安装的Maven…

JS 问题集锦

【1】js页面跳转 和 js打开新窗口方法 第一种&#xff1a;<script language"javascript" type"text/javascript">window.location.href"http://www.xlfun.com/login.php?backurl"window.location.href; </script>第二种&#xff1a…

重温Observer模式--热水器·改(转载)

引言 在 C#中的委托和事件 一文的后半部分&#xff0c;我向大家讲述了Observer(观察者)模式&#xff0c;并使用委托和事件实现了这个模式。实际上&#xff0c;不使用委托和事件&#xff0c;一样可以实现Observer模式。在本文中&#xff0c;我将使用GOF的经典方式&#xff0c;再…

龙图 VP 李翀:数据化运营及云计算下的运维

文 | 龙图 VP 李翀原文地址&#xff1a;当游戏遇上大数据和云计算——谈数据化运营及云计算下的运维龙图做了8年的游戏&#xff0c;真正快速发展起来是在移动互联网这个时代。随着刀塔快速的扩张&#xff0c;我们在各个领域都遇到了非常多的之前没有想到过的状态。发现云计算其…

鼠标移动时,光标相对于对象的位置

鼠标在一个物体上移动时&#xff0c;能够计算出光标相对于任何其它对象的相对位置。 Code<Grid x:Name"LayoutRoot" Background"White"> <Grid HorizontalAlignment"Left" VerticalAlignment"Top" Name"grid1&q…

怎么判断一个字符串的最长回文子串是否在头尾_【Leetcode每日打卡】最长回文串...

干货预警&#xff1a;所有文章都会首发于我的公众号【甜姨的奇妙冒险】&#xff0c;欢迎watch。一、来历&#xff1a;力扣从3月开始开启了每日一题打卡活动&#xff0c;于是跟风加入了打卡大军&#xff0c;这两天写评论、发题解&#xff0c;没想到反响还不错&#xff0c;收到了…

.NET平台下WEB应用程序的部署(安装数据库和自动配置)

.NET平台下WEB应用程序的部署(安装数据库和自动配置)李洪根在.NET平台下&#xff0c;部署 Web 解决方案是比较方便的。我们可以利用Visual Studio.NET 2003添加一个WEB安装项目&#xff0c;在部署的“文件系统编辑器”中添加项目的主输出和内容文件&#xff0c;非常简易地完成安…

苹果原壁纸高清_全面屏壁纸高清 | 电影经典台词截图高清

iPhonex手机壁纸高清(苹果xs壁纸&#xff0c;苹果xr壁纸&#xff0c;iPhone11壁纸&#xff0c;安卓全屏壁纸)火影壁纸高清&#xff0c;经典电影台词截图拼接壁纸&#xff0c;电影《去他妈的世界》壁纸&#xff0c;欧美电影截图加上经典台词&#xff0c;2020好看的手机壁纸&…

python字符串切片用法_详解Python字符串切片

在python中,我们定义好一个字符串,如下所示。 在python中定义个字符串然后把它赋值给一个变量。 我们可以通过下标访问单个的字符,跟所有的语言一样,下标从0开始(==,我自己都觉得写的好脑残了) 这个时候呢,我们可以通过切片的方式来截取出我们定义的字符串的一部分。 使用…

azkaban config: nodes:_关于Nordic SDK的sdk.config.h

使用MDK对Nordic SDK开发&#xff0c;离不开sdk.config.h。请看以下两个视图&#xff1a;Text Editor视图Configuration Wiard视图咋一看挺神奇的&#xff0c;配置视图话&#xff0c;方便。具体实现和规则就不一一介绍了&#xff0c;网页搜“MDK中Configuration Wiard的使用”。…

SilverLight开发系列第1步:搭建开发环境

来自 http://www.cnblogs.com/kaima/archive/2008/08/17/1269637.html 在缺乏SilverLight中文教程的今天&#xff0c;新人要入门不容易&#xff0c;所以我根据自己阅读英文原档和实践经验&#xff0c;总结一个系列。首先介绍的是开发环境的搭建。 个人强烈推荐安装英文版的开发…

php使用smtp.sina.com邮箱发送邮件

2019独角兽企业重金招聘Python工程师标准>>> 需要写一个smtp发送类 <?php set_time_limit(120);class smtp {/* Public Variables */var $smtp_port;var $time_out;var $host_name;var $log_file;var $relay_host;var $debug;var $auth;var $user;var $pass;var…

java 不存在就创建_Java 判断多级路径是否存在,不存在就创建

Java 判断多级路径是否存在&#xff0c;不存在就创建方案一&#xff1a;(带文件名的Path&#xff1a;如&#xff1a;D:\news\2014\12\abc.text)public boolean isexitsPath(String path)throws InterruptedException{String [] pathspath.split("\\\\");StringBuffer…

asynchttpclient 超时_DNF:95更新前还能免费获得一件超时空装备?但这个任务一定完成...

现在距离95版本更新还有16天的时间&#xff0c;在前段时间体验服更新的内容中&#xff0c;相信玩家们已经对新版本了解的差不多了。最受玩家关注的就是装备升级方面的一些内容&#xff0c;都说95版本是一个土豪专属副本&#xff0c;但是小编并不那么认为&#xff01;从材料上来…

sqllite开发安卓项目_【兼职项目】预算3万开发无线温度电流传感,2万开发直流电机打磨机控制...

【个人/团队兼职项目】是小包为大家筛选的酬金预算≤3万元的中小型软硬件兼职项目&#xff0c;适合高级工程师、技术团队服务商竞标&#xff0c;从而赚取“零花钱”。个人/团队兼职项目&#xff08;酬金≤3万元&#xff09;1、摄像头在安卓开发板上成像项目预算&#xff1a;&am…