C# string 的==和Equals的比较

在程序中我们经常碰到比较2个字符串是否相等,那么他们各自的性能又如何了?个人推崇用字符串的实例方法Equals,

它的性能相对较高。

 

 class Program
    {
        static void Main(string[] args)
        {
            string str1 = "abcdef";
            string str2 = "abc";
            str2 = str2 + "def";
            PerFormanceCounter p = new PerFormanceCounter();
            p.Reset();
            Console.WriteLine(str1 == str2);
            p.Stop();
            Console.WriteLine(p.ElapsedSeconds);

            p.Reset();
            Console.WriteLine(string.Equals(str1, str2));
            p.Stop();
            Console.WriteLine(p.ElapsedSeconds);
            /*
            
             */
            p.Reset();
            Console.WriteLine(str1.Equals(str2));
            p.Stop();
            Console.WriteLine(p.ElapsedSeconds);

            str2 = string.Intern(str2);
            p.Reset();
            Console.WriteLine(string.ReferenceEquals(str1, str2));
            p.Stop();
            Console.WriteLine(p.ElapsedSeconds);

            Console.ReadLine();
         
        }
    }
    public class PerFormanceCounter
    {
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceCounter(ref long x);
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceFrequency(ref long x);

        private long frequency;
        private long start, end;

        public PerFormanceCounter()
        {
            QueryPerformanceFrequency(ref frequency);
        }

        public void Reset() { QueryPerformanceCounter(ref start); }

        public void Stop() { QueryPerformanceCounter(ref end); }

        public double ElapsedSeconds
        {
            get
            {
                return (end - start) * 1.0 / frequency;
            }
        }
        public long Frequency
        {
            get
            {
                return frequency;
            }
        }
    }
运行效果如图:


从运行结果来看string.ReferenceEquals -> String的实例方法Equals->String的静态方法Equals->string 的 == 性能依次降低。 注意string.ReferenceEquals是比较的引用类型,在程序第一次 运行它的性能可能比Equals低, 但是怎么都比 “==”性能高。

我们来阅读源码看看为什么:

   public static bool operator == (String a, String b) { 
        return String.Equals(a, b);
     }
    public static bool Equals(String a, String b) {
         if ((Object)a==(Object)b) { 
             return true; 
         }
 
         if ((Object)a==null || (Object)b==null) {
             return false;
         }
 
         return EqualsHelper(a, b);
     } 
 
         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
         public bool Equals(String value) {
         if (value == null)
         {
             // exception will be thrown later for null this 
             if (this != null) return false;
         } 
 
         return EqualsHelper(this, value);
          } 

             
             private unsafe static bool EqualsHelper(String strA, String strB)
     { 
         int length = strA.Length; 
         if (length != strB.Length) return false;
 
         fixed(char* ap = strA) fixed(char* bp = strB)
         {
             char* a = ap;
             char* b = bp; 

             // unroll the loop 
#if AMD64 
             // for AMD64 bit platform we unroll by 12 and
             // check 3 qword at a time. This is less code 
             // than the 32 bit case and is shorter
             // pathlength

             while (length >= 12) 
             {
                 if (*(long*)a     != *(long*)b) break; 
                 if (*(long*)(a+4) != *(long*)(b+4)) break; 
                 if (*(long*)(a+8) != *(long*)(b+8)) break;
                 a += 12; b += 12; length -= 12; 
             }
#else
             while (length >= 10)
             { 
                 if (*(int*)a != *(int*)b) break;
                 if (*(int*)(a+2) != *(int*)(b+2)) break; 
                 if (*(int*)(a+4) != *(int*)(b+4)) break; 
                 if (*(int*)(a+6) != *(int*)(b+6)) break;
                 if (*(int*)(a+8) != *(int*)(b+8)) break; 
                 a += 10; b += 10; length -= 10;
             }
#endif
 
             // This depends on the fact that the String objects are
             // always zero terminated and that the terminating zero is not included 
             // in the length. For odd string sizes, the last compare will include 
             // the zero terminator.
             while (length > 0) 
             {
                 if (*(int*)a != *(int*)b) break;
                 a += 2; b += 2; length -= 2;
             } 

             return (length <= 0); 
         } 
     }
其实看了源码大家不难发现 == 调用的是String.Equals方法,所以性能比String.Equals低。而String.Equals首先检查2个对象引用是否相等,如果相等直接返回,否者在调用EqualsHelper方法。 而string的实例方法是直接调用EqualsHelper方法,所以它的性能最高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值