日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

strlen的神奇实现

發布時間:2023/12/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 strlen的神奇实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://blog.delphij.net/2012/04/freebsd-strlen3.html


與 Pascal 等語言不同,C 的字符串并不保存串的長度,而是在字符串末尾以 nul 字符('\0')來表示字符串結束。這個設計決策是上世紀 60 年代作出的,有都市傳說是為了省幾個字節的空間,不過我個人認為也可能是因為匯編里面到處都是判斷是否碰到了 0 的操作。不管怎么說,這個設計令 strlen 變成了一個 O(n) 的操作。

早期的 BSD Unix 采用的 strlen 是非常簡單的循環比較每一個字符是不是 nul。1993年,J.T. Conklin 為 i386 系統撰寫了一個匯編的版本,這個版本的核心用的是 REP SCASB,實際上和 C 版本的算法是一樣的(不知道為什么 C 編譯器不能寫出同樣的代碼)。

為了配合 x86_64 平臺,后來又有了一個新的匯編版本,這個版本的核心算法是按字匹配,找到包含 nul 字符的字之后,再在其中用原始的算法找到 nul 字符。

我在 2009 年根據這個 x86_64 版本的匯編的思路重寫了一個 C 的版本,并在 2010 年做了一次最終的變動,形成了目前的版本。這個版本的大致流程如下:

  • 判斷第一個字中是否存在 nul,如果存在,掃描查找其中有效位置的 nul 字符;
  • 按字掃描剩余的字符串;如果發現字中帶 nul,則掃描并返回其位置。

實現細節

整個算法中,比較難理解的是判斷字中是否帶 nul 字符。具體的方法是計算兩個中間變量:

  • a = (x - 0x01010101)
  • b = (~x & 0x80808080)
  • 計算 a & b == 0
  • 這里的 0x01010101 和 0x80808080 可以進一步擴展。第一步,如果每個字節都 <= 0x7f,只要那個字節不是 0,做差必然得到一個 < 0x80 的結果(換言之,最高位是0);如果有字節 >= 0x81,做差必然得到一個 > 0x80 的結果。對于等于 0x80 的情況,我們會得到 0x7f,但這并不重要。

    注意到,此處,任何一個字節的最高 bit 是 1 的話,則必然是前面兩種情況之一:要么這個字節是 0,要么它 >= 0x81。如果不考慮后一種情況,我們直接把結果 & 0x80808080 即可;然而,由于需要考慮后一種情況,我們接著計算 ~x & 0x80808080。若某一字節 >= 0x80,則對應的結果將是那個位置上的一個 0x80。

    將兩個結果做邏輯與,若結果非 0 則說明至少有一個字節是 nul。

    這里說起來的過程很復雜,但事實上計算機計算這些要比一個一個去判斷每個字節是否為 0 要快。這里有幾方面的原因:

    • 按字長做操作,令 CPU 無需模擬按字節為長度操作的情況,后者是比較耗時的;
    • 前兩步操作(分別計算a, b)可以并發執行;
    • 最后一步操作可以直接在兩個寄存器之間進行,且是速度較快的與運算;

    在實際的實現中,還有一些其他的技巧。

    第一個技巧是,從第一個小節就開始用字長的操作。一般來說,內存分配器在分配內存時是以字邊界開始的,因此,通常 strlen() 的操作的指針都是對齊的。不過,即使不是,這個指針往前退到第一個整字位置(例如字長=8,指針 0x9,則退回 0x8)開始的一個整字必然是在同一個內存頁上,因此這個訪問不會越界。如果在這個整字中有 nul 字符,我們只需從指針開始處掃描到第一個整字結尾的地方即可知道是不是真的找到了字符串的末尾。

    由于整個字已經在處理器緩存中,后續的循環也不會太慢。

    第二個技巧與此類似,我們一直都用整字的操作。如果字的起始地址在內存頁中,則終止地址也必然在同一個內存頁中。這個訪問同樣也不會發生意外越界(盡管在分配內存時可能出現類似分配了 4 個字節,但訪問了 8 個字節的情況)。換言之,如果程序原先不會發生越界異常,則現在也不會。

    這個版本的 strlen 源代碼可以在?這里?找到。


    轉載于:https://www.cnblogs.com/marryZhan/archive/2012/05/23/2797292.html

    總結

    以上是生活随笔為你收集整理的strlen的神奇实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 少妇高潮一区二区三区69 | 亚洲精选久久久 | 中文亚洲av片不卡在线观看 | 欧美精品在线视频观看 | 国产精品毛片一区二区三区 | 久久国产小视频 | 日本高清免费不卡视频 | 欧美日韩看片 | xxxx国产精品 | 欧美成人午夜剧场 | 国产靠逼视频 | 国产一区福利 | 特种兵之深入敌后高清全集免费观看 | 黄网站免费视频 | 国产一区在线播放 | 蜜桃在线一区二区三区 | 一区二区三区视频免费看 | 极品美女啪啪 | 日韩精品手机在线 | 乱妇乱女熟妇熟女网站 | 精品一区二区三区中文字幕 | 国产二区自拍 | av鲁丝一区鲁丝二区鲁丝三区 | 激情精品 | 久久11| 精品久久久久久无码人妻 | 女人下面无遮挡 | 国产性生活毛片 | 日本不卡一区在线观看 | 欧美日韩国产在线观看 | 五月婷婷狠狠爱 | 成人性爱视频在线观看 | 麻豆午夜 | 秋葵视频在线 | 亚洲欧美成人一区二区 | 精品国产av一区二区三区 | 日批视频免费在线观看 | 色屁屁| 久久综合九色综合网站 | 免费一级毛片麻豆精品 | 四虎永久在线精品 | 老太婆av| 香蕉视频三级 | 小柔的淫辱日记(1~7) | 亚洲性猛交xxxx乱大交 | 91在线精品秘密一区二区 | 99精品热 | 成 人 a v天堂 | 欧美a∨| 97在线观看免费高清 | 久久深夜福利 | 黄色美女大片 | 日本精品视频在线观看 | 久久久久久久极品内射 | 中文字幕一区视频 | 九九综合九九 | 五月婷婷激情五月 | 91第一页| 开心激情网站 | 少妇床戏av | 黄色特级片 | 亚洲日本免费 | 男女免费毛片 | 天天射日日操 | 亚洲美女中文字幕 | 欧美日韩成人免费观看 | 四季av国产一区二区三区 | 人人精品视频 | 国产三级三级三级 | 涩涩网站视频 | 亚洲美女性视频 | 亚洲午夜精品久久 | 国产黄色av | 男女黄色又爽大片 | 又黄又爽在线观看 | av片一区二区 | 色偷偷影院| 国产第一色 | 天天尻 | 亚洲一区亚洲二区 | 欧美性受xxxx黑人xyx性爽 | 国产一级aa大片毛片 | 亚洲喷潮 | 谁有av网址| 久久涩视频 | 中文字幕亚洲精品在线观看 | 国产精品视频播放 | 国产初高中真实精品视频 | 三级av免费看 | 天天插天天狠 | 久久中文字幕无码 | 九色亚洲 | 97人妻人人揉人人躁人人 | 91麻豆国产在线 | 丝袜一区二区三区 | 成人xxx| 亚洲无码精品免费 | 天天天操操操 | 在线观看一区二区视频 |