天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

總結(jié)字符串比較函數(shù)

  最近一段時間一直在重看CLR via C# , 這次把字符串比較的函數(shù)總結(jié)下。

  1.Compare和CompareTo大PK

  首先是我們最常用的String.Compare和CompareTo實(shí)例方法,先來看看這兩個方法:

image

  我們通過這個可以直觀地看到,String的靜態(tài)方法要比CompareTo多出好多的方法重載,其實(shí)這也是兩者的最大區(qū)別,也就是說String.Compare有著更多的功能選項(xiàng)供我們控制。

  其中主要包含著三個方面:

  A. 文化信息

  B. CompareOptions

  C. 比較的開始和結(jié)束位置

  對于文化信息,我們可以看下Compare的反編譯結(jié)果:

image

  對于Compare來說,他會通過傳遞進(jìn)來的文化信息來調(diào)用對應(yīng)的比較。

  而CompareTo則是:

image

  CompareTo則會調(diào)用與當(dāng)前線程相關(guān)聯(lián)的文化信息。

  對于文化信息來說,還有著這樣一個枚舉選項(xiàng):StringComparison:

  下面讓我們來看下StringComparison枚舉:

image

  對于該枚舉,共有如上六個枚舉值。該枚舉主要對應(yīng)著當(dāng)前的文化信息,大小寫,以及排序規(guī)則。

 

image

  這就意味著,如果我們進(jìn)行國際化的時候,字符串比較必須使用String.Compare靜態(tài)方法。

  下面來看下CompareOptions:

image

  最后看下含開始和結(jié)束位置的String.Compare方法:

image

  方法本身很簡單,而方法鏈的最末端使用的是:

image

  一個內(nèi)部比較字符串的非托管方法,而方法的具體內(nèi)容,我無從而知,但是可以明確的是,這一定是一個高效的比較算法。

  因此,當(dāng)我們每次SubString的時候,當(dāng)我們ToLower的時候,我們不妨都在這里使用String.Compare,是不是為我們節(jié)省了很多空間,提高了很大效率呢?

  因此,我在這里建議,如果可能,我們盡可能地使用String.Compare方法來代替CompareTo方法!

  2. 被遺忘的CompareOrdinal

  讓我們先來看下CompareOrdinal的源碼:

private static unsafe int CompareOrdinalHelper(string strA, string strB){    int num = Math.Min(strA.Length, strB.Length);    int num2 = -1;    fixed (char* chRef = &strA.m_firstChar)    {        fixed (char* chRef2 = &strB.m_firstChar)        {            char* chPtr = chRef;            char* chPtr2 = chRef2;            while (num >= 10)            {                if (*(((int*)chPtr)) != *(((int*)chPtr2)))                {                    num2 = 0;                    break;                }                if (*(((int*)(chPtr + 2))) != *(((int*)(chPtr2 + 2))))                {                    num2 = 2;                    break;                }                if (*(((int*)(chPtr + 4))) != *(((int*)(chPtr2 + 4))))                {                    num2 = 4;                    break;                }                if (*(((int*)(chPtr + 6))) != *(((int*)(chPtr2 + 6))))                {                    num2 = 6;                    break;                }                if (*(((int*)(chPtr + 8))) != *(((int*)(chPtr2 + 8))))                {                    num2 = 8;                    break;                }                chPtr += 10;                chPtr2 += 10;                num -= 10;            }            if (num2 == -1)            {                goto Label_00F1;            }            chPtr += num2;            chPtr2 += num2;            int num3 = chPtr[0] - chPtr2[0];            if (num3 != 0)            {                return num3;            }            return (chPtr[1] - chPtr2[1]);        Label_00D7:            if (*(((int*)chPtr)) != *(((int*)chPtr2)))            {                goto Label_00F5;            }            chPtr += 2;            chPtr2 += 2;            num -= 2;        Label_00F1:            if (num > 0)            {                goto Label_00D7;            }        Label_00F5:            if (num > 0)            {                int num4 = chPtr[0] - chPtr2[0];                if (num4 != 0)                {                    return num4;                }                return (chPtr[1] - chPtr2[1]);            }            return (strA.Length - strB.Length);        }    }}

  方法很長,但是很簡單,即使是Reflector 出來的變量名很BT,但是我們也可以大致看個究竟。

  他是將整個字符串每5個字符(10個字節(jié))分成一組,然后逐個比較,找到第一個不相同的ASCII碼后退出循環(huán)。并且求出兩者的ASCII碼的差。不過我很費(fèi)解的是微軟為什么要把這個實(shí)現(xiàn)的如此麻煩。只能等到周一再求解了。

  但是在CLR via C#上有這樣的話:這個方法比其他方法都要快。我想應(yīng)該是有一定道理的吧。

  所以當(dāng)我們比較大小的時候,盡量使用CompareOrdinal方法。

  3. 常用的Equals方法

  先來看Equals實(shí)例方法:

image

  方法會首先進(jìn)行合法性判斷,然后比較兩者是否指向同一塊引用,接下來調(diào)用EqualsHelper方法(不清楚微軟為什么很沉迷于XXXHelper這個命名,難道XXXHelper這個名詞不應(yīng)該是一個類名么?)

private static unsafe bool EqualsHelper(string strA, string strB){    int length = strA.Length;    if (length != strB.Length)    {        return false;    }    fixed (char* chRef = &strA.m_firstChar)    {        fixed (char* chRef2 = &strB.m_firstChar)        {            char* chPtr = chRef;            char* chPtr2 = chRef2;            while (length >= 10)            {                if ((((*(((int*)chPtr)) != *(((int*)chPtr2))) || (*(((int*)(chPtr + 2))) != *((
(int*)(chPtr2 + 2))))) || ((*(((int*)(chPtr + 4))) != *(((int*)(chPtr2 + 4)))) || (*(((int
*)(chPtr + 6))) != *(((int*)(chPtr2 + 6)))))) || (*(((int*)(chPtr + 8))) != *(((int*)(chPt
r2 + 8))))) { break; } chPtr += 10; chPtr2 += 10; length -= 10; } while (length > 0) { if (*(((int*)chPtr)) != *(((int*)chPtr2))) { break; } chPtr += 2; chPtr2 += 2; length -= 2; } return (length <= 0); } }}

  迷糊了,又是這樣的算法,我實(shí)在不了解10字節(jié)究竟有什么奧秘,周一如果問到答案會對其進(jìn)行解釋。

  然而,值得肯定的是,由于是非安全代碼的比較,所以效率要比我們用安全代碼高得多。

  接下來看看Equals靜態(tài)方法:

image

  (關(guān)于==的運(yùn)算符重載之前有誤,下文會解釋清楚)

  4. 總結(jié)

  本文主要介紹了String類型的比較方法,也留下了一些疑問,也希望可以得到各位的解答。

NET技術(shù)總結(jié)字符串比較函數(shù),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产又粗又猛又爽黄老大爷 | 99久久免费国内精品 | 北原多香子qvod | 日本A级作爱片金瓶双艳 | 色中色入口2015 | 99视频在线观看视频 | 亚洲精品久久久久久久蜜臀老牛 | 欧美精品九九99久久在观看 | 亚洲国产成人一区二区在线 | 推倒美女总裁啪啪 | 国产午夜在线视频 | 99热久久视频只有精品6 | 久久re这里视频只精品首页 | 国产欧美精品国产国产专区 | 在线 无码 中文 强 乱 | 24小时日本在线观看片免费 | 护士日本xx厕所 | 国产 亚洲 中文字幕 久久网 | XXX欧美性兽交| 国产精品嫩草影院一区二区三区 | 十分钟免费观看高清视频大全 | 两个人的视频日本在线观看完整 | 男神插曲女生软件完整版 | 任你躁国语自产二区在线播放 | 越南女子杂交内射BBWXZ | 国产第81页 | 最新中文字幕在线视频 | 国产精品色无码AV在线观看 | 妈妈的朋友6未删减版完整在线 | 国产精品JK白丝AV网站 | 白丝女仆被强扒内裤 | 为什么丈夫插我我却喜欢被打着插 | 男男高H啪肉Np文多攻多一受 | 日本人bbwbbwbbwbbw | 天天狠狠色综合图片区 | 综合精品欧美日韩国产在线 | 日本无码人妻丰满熟妇5G影院 | 嘿嘿视频在线观看 成人 | 亚洲.欧美.中文字幕在线观看 | 亚洲日本欧美国产在线视 | 国产AV高清怡春院 |