字符串相关的性能规则 - TOMMYHU - 专注互联网开发及运营技术,提供相关资料及软件下载,奇趣网络时事评论!
Mar 5

字符串相关的性能规则 不指定

tommyhu , 21:07 , ASP.NET , Comments(0) , Trackbacks(0) , Reads(2997) , Via Original Large | Medium | Small

                                                

            
                                                                                                                                                                                        
【摘要】
规则描述:
                        字符串导致性能下降的主要原因是字符串(System.String)的不可变性(immutable)。因此,在创建不必要的字符串时,除了创建动作本身的性能消耗,为额外创建的字符串对象分配的内存,以及对它们进行垃圾搜集,也都是额外的开销。
            
            
            
                        
                                    
            
            

规则简介:  

            

       今天介绍字符串相关的性能规则(  Performance Rules )。字符串是我们程式开发中最频繁使用的对象之一,因此,一旦使用不当,更容易导致性能下降。  

            

       下面是这三条相关规则:  

            

      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                        

规则  ID

                        
                        

分类  

                        
                        

规则名称  

                        
                        

中文译名  

                        
                        

确定性  

                        
                        

CA1807

                        
                        

Performance

                        
                        

AvoidUnnecessaryStringCreation

                        
                        

避免创建不必要的字符串  

                        
                        

90   

                        
                        

CA1818

                        
                        

Performance

                        
                        

DoNotConcatenateStringsInsideLoops

                        
                        

不要在循环中串联字符串  

                        
                        

75   

                        
                        

CA1820

                        
                        

Performance

                        
                        

TestForEmptyStringsUsingStringLength

                        
                        

使用字符串长度测试是否有空字符串  

                        
                        

95   

                        
            

      

            

      

            

规则描述:  

            

       字符串导致性能下降的主要原因是字符串(  System.String )的不可变性(  immutable )。因此,在创建不必要的字符串时,除了创建动作本身的性能消耗,为额外创建的字符串对象分配的内存,以及对它们进行垃圾搜集,也都是额外的开销。  

            

            

       CA1807—— 避免创建不必要的字符串。具体而言,这条规则只检查以下的三种情形,即不必要的使用  ToUpper   ToLower 方法引发的字符串创建。

            

l         对同一个字符串实例多次调用  ToLower   ToLowerInvariant   ToUpper   ToUpperInvariant   

            

l         对由于调用  ToLower   ToUpper 而创建的字符串调用  System.String.Equals   System.String.op_Equality(System.String,System.String)   System.String.op_Inequality(System.String,System.String)   

            

l         将由于调用  ToLower   ToUpper 而创建的字符串传递给  System.Collections.Specialized.HybridDictionary 的成员。  

            

      

            

CA1818 ——不要在循环中串联字符串,在以迭代方式串联字符串时会创建多个未引用而且必须进行垃圾回收的字符串,因此,会导致严重的性能问题。  

            

            

字符串类对一些常用操作做了性能优化,比如判断空字符串。  

            

CA1820 ——使用字符串长度测试是否有空字符串。  

            

使用  System.String.Length 属性或  System.String.IsNullOrEmpty(System.String) 方法比较字符串要比使用  Equals 的速度快得多。这是因为与  IsNullOrEmpty 或者为检索  Length 属性值并将其与零比较所需执行的指令数相比,  Equals 执行更多的  MSIL 指令。  

            

您应该注意,  Equals   Length == 0 对于空字符串的行为表现不同。如果您试图获取空字符串的  Length 属性的值,公共语言运行库将引发  System.NullReferenceException 。如果比较空  (null) 字符串和空  (empty) 字符串,则公共语言运行库不会引发异常;比较将返回  false 。对空字符串进行测试不会显著影响这两种方法的相对性能。当目标为  .NET Framework 2.0 时,使用  IsNullOrEmpty 方法。否则,在可能的情况下请使用  Length == 比较。  

            

            

            

如何修复冲突:  

            

CA1807—— 避免创建不必要的字符串。  

            

请通过移除对  ToLower   ToUpper 的调用来避免创建不必要的字符串。下列修复与   说明   部分中的编号对应:  

            

l         将第一次调用  ToLower   ToUpper 的结果赋给新变量,然后使用此变量(而非其余调用)。  

            

l         将对  Equals   op_Equality   op_Inequality 的调用替换为对  System.String.Compare 的不区分大小写的调用。  

            

l         使用不区分大小写的  HybridDictionary ,它是通过将  true 作为  caseInsensitive 参数传递给构造函数来创建的。  

            

            

CA1818 ——不要在循环中串联字符串。  

            

请使用  StringBuilder 类的实例在迭代语句内部生成字符串。生成字符串之后,使用  System.Text.StringBuilder.ToString 方法访问字符串。  

            

            

CA1820 ——使用字符串长度测试是否有空字符串。  

            

请将比较方法更改为使用  Length 属性测试空字符串。如果目标为  .NET Framework 2.0 ,则使用  IsNullOrEmpty 方法。  

            

            

            

示例代码:  

            

       以下的示例代码来自  HI0 实际项目  

            

  

                                                                                                                        
                        

                        

     // 违反  CA1807 避免创建不必要的字符串  

                        

    if (element.GetAttribute("enabled").ToUpper() ==  "TRUE")

                        

    {

                        

        inboundDays = int.Parse(element.GetAttribute("value"));

                        

    }

                        

    else

                        

    {

                        

        inboundDays =  -1;

                        

    }

                        

                        

    // 符合  CA1807   Performance 更好的写法  

                        

    if (String.Compare(element.GetAttribute("enabled"),  "TRUE", true)==0)

                        

    {

                        

        inboundDays = int.Parse(element.GetAttribute("value"));

                        

    }

                        

    else

                        

    {

                        

        inboundDays =  -1;

                        

    }

                        

                        
            

  

                                                                                                                        
                        

                        

    //…

                        

    string htmlRowData = "";

                        

    for(int i = 0; i  < messageDataTable.Rows.Count; i++)

                        

    {

                        

        DataRow row =  messageDataTable.Rows[i];

                        

        string htmlRowTemp = htmlRow;

                        

        foreach(DataColumn column in messageDataTable.Columns)

                        

        {

                        

            htmlRowTemp =  htmlRowTemp.Replace("$" + column.ColumnName.ToLower() + "$",  row[column.ColumnName.ToLower()].ToString());

                        

        }

                        

        // 违反  CA1818 不要在循环中串联字符串,应该修改为使用  StringBuilder 进行串联  

                        

        htmlRowData =  htmlRowData + htmlRowTemp;

                        

    }

                        

                        
            

  

                                                                                                                        
                        

                        

     string subSql = GetSubSql(newStatus, completedStatus,  unCompletedStatus);

                        

    // 违反  CA1820 使用字符串长度测试是否有空字符串  

                        

    if(subSql != "")

                        

    {

                        

         sqlTrans.Append(subSql);

                        

    }

                        

                        

    // 符合  CA1820   Performance 更好的写法  

                        

    if(subSql != null  && subSql.Length != 0)

                        

    {

                        

         sqlTrans.Append(subSql);

                        

    }

                        

                        
            

  

            

  

            

Tips   

            

       介绍  FxCop 规则的时候,其实会注意到每一条规则都附带很多说明性的属性,因此我们会在  Tips 中做一些说明    

            

       今天介绍一下  Type 的含义,规则类型(姑且这么翻译吧)是用来标识这条规则所关注的一个主要问题域的,这些问题域包括性能规则,设计规则等等。举例子来说,性能规则都是从提升代码性能的角度提出的,如果说我们这个应用非常关心性能的问题的话,那么我们可以选择符合更多的性能规则。  

            

       区分规则类型是便于实际应用的,这样不同的应用就可以根据不同的需求,来选择合适的规则了。  

            

       顺便说一下,迈向高质量代码活动推出的  20 条规则都是属于设计规则、性能规则和用法规则这三组以内的,因为这三组规则的通用性更好一些,而且所包含的规则数量也是最多的。而类似可移植性相关的规则,也许视情况来要求更好一些。  

            

      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                        

规则类型  

                        
                        

描述  

                        
                        

包含规则数  

                        
                        

Design Rules

                        
                        

设计规则——以支持符合  .NET Framework 设计指南的正确的类库设计  

                        
                        

59

                        
                        

Globalization Rules

                        
                        

全球化规则——以支持  World-Ready 的类库和应用程序  

                        
                        

7

                        
                        

Interoperability Rules

                        
                        

互操作性规则——以支持和  COM Client 的交互  

                        
                        

16

                        
                        

Mobility Rules

                        
                        

机动性规则——以支持  efficient power usage

                        
                        

2

                        
                        

Naming Rules

                        
                        

命名规则——以支持符合  .NET Framework 设计指南的命名习惯  

                        
                        

26

                        
                        

Performance Rules

                        
                        

性能规则——以支持高性能的类库和应用程序  

                        
                        

22

                        
                        

Portability Rules

                        
                        

移植性规则——以支持不同平台间可移植性的相关  

                        
                        

3

                        
                        

Security Rules

                        
                        

安全性规则——以支持更安全的类库和应用程序  

                        
                        

26

                        
                        

Usage Rules

                        
                        

使用性规则——以支持  .NET Framework 的正确用法  

                        
                        

40

                        
                        

        

            
            

▲返回顶部
相关日志(relate log)

Last modified by tommyhu on2013/03/06 19:08

Add a comment

Nickname

emotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemot