String 和它的副本可以共享相同的底層記憶體嗎?Ruby 中有寫時復制嗎?
我有一個大的、凍結的字串,我想更改它的編碼。但我不想為了這樣做而復制整個字串。對于背景關系,這是將值傳遞給具有該bytes型別且僅接受 Encoding::ASCII_8BIT 的 Google Protocol Buffer。
big_string.freeze
MyProtobuf::SomeMessage.new(
# I would prefer not to have to copy the whole string just to
# change the encoding.
value: big_string.dup.force_encoding(Encoding::ASCII_8BIT)
)
uj5u.com熱心網友回復:
它對我來說似乎作業得很好:(使用 MRI/YARV 1.9、2.x、3.x)
require 'objspace'
big_string = Random.bytes(1_000_000).force_encoding(Encoding::UTF_8)
big_string.encoding #=> #<Encoding:UTF-8>
big_string.bytesize #=> 1000000
ObjectSpace.memsize_of(big_string) #=> 1000041
dup_string = big_string.dup.force_encoding(Encoding::ASCII_8BIT)
dup_string.encoding #=> #<Encoding:ASCII-8BIT>
dup_string.bytesize #=> 1000000
ObjectSpace.memsize_of(dup_string) #=> 40
這 40 個位元組是在 Ruby 中容納一個物件 (RVALUE) 的大小。
請注意,不是dup/force_encoding(Encoding::ASCII_8BIT)還有b它會立即回傳二進制編碼的副本。
有關更深入的資訊,請參閱 2012 年 (Ruby 1.9) 中有關 Ruby 中的寫時復制/共享字串的博文:
- Seeing double:Ruby 如何共享字串值
摘自作者的書《顯微鏡下的紅寶石》:(第 265 頁)
在內部,JRuby 和 MRI 都對字串和其他資料使用稱為寫時復制的優化。這個技巧允許兩個相同的字串值共享同一個資料緩沖區,這既節省了記憶體又節省了時間,因為 Ruby 避免了不必要地單獨復制相同的字串資料。
uj5u.com熱心網友回復:
String 和它的副本可以共享相同的底層記憶體嗎?Ruby 中有寫時復制嗎?
Ruby 語言規范中沒有任何內容可以阻止這種情況。Ruby 語言規范中也沒有任何強制執行的內容。
一般來說,Ruby 語言規范試圖對所有與記憶體管理、空間復雜度、步驟復雜度或時間復雜度相關的事情保持沉默。這并不是 Ruby 語言規范獨有的,大多數語言規范都試圖為實作者留出盡可能多的余地。換句話說,語言規范傾向于指定語法和語意,而離開語用學取決于實施者。(C 有點例外,因為它指定了標準庫中演算法的空間和時間復雜度。)即使是通常被認為是一種可以讓您完全控制一切的語言的 C,實際上也沒有指定諸如精確的記憶體布局——例如,由于標準中術語寬度uint16_t的定義,實際上允許 a 占用超過 16 位!
每個實作者都可以自由地實作他們想要的字串,只要它們符合 Ruby 語言規范中定義的語意。
如果我沒記錯的話,Rubinius和TruffleRuby 都曾一度嘗試過String基于Ropes的實作。TruffleRuby 的首席開發人員Chris Seaton撰寫了一篇關于該實作的論文。但是,我不知道他們是否還在使用它。(我知道 TruffleRuby 最近轉向了Truffle Strings,我不確定它們的底層表示是什么……或者它們是否甚至保證特定的底層表示。)
但是,“您必須查看規范”的答案存在問題:不幸的是,與許多其他編程語言不同,Ruby 語言規范并不作為單個檔案存在于一個地方。Ruby 沒有一個單一的正式規范來定義某些語言結構的含義。
有幾種資源,它們的總和可以被認為是一種 Ruby 編程語言的規范。
其中一些資源是:
- ISO/IEC 30170 :2012資訊技術——編程語言——Ruby規范 ——請注意,ISO Ruby 規范是在 2009 年至 2010 年左右撰寫的,其特定目標是讓當時所有現有的 Ruby 實作都能輕松兼容。由于 YARV 和 MacRuby 僅實作 Ruby 1.9 ,MRI 僅實作 Ruby 1.8 及更低版本,而 JRuby、XRuby、Ruby.NET 和 IronRuby(當時)僅實作 Ruby 1.8 的子集,這意味著 ISO Ruby 規范僅包含Ruby 1.8 和 Ruby 1.9 共有的功能。此外,ISO Ruby 規范特別旨在最小化并且僅包含撰寫 Ruby 程式絕對需要的功能。正因為如此,它確實體如僅指定
String它非常廣泛(因為它們在 Ruby 1.8 和 Ruby 1.9 之間發生了顯著變化)。它顯然也沒有指定在撰寫 ISO Ruby 規范后添加的功能,例如 Ractors 或模式匹配。 - Ruby Spec Suite 又名
ruby/spec——請注意,ruby/spec不幸的是,它遠未完成。然而,我非常喜歡它,因為它是用 Ruby 而不是“ISO-standardese”撰寫的,這對于 Rubyist 來說更容易閱讀,而且它還可以作為一個可執行的一致性測驗套件。 - The Ruby Programming Language by David Flanagan and Yukihiro 'matz' Matsumoto – 這本書由 David Flanagan 和 Ruby 的創造者 matz 共同撰寫,作為 Ruby 的語言參考。
- Programming Ruby作者:Dave Thomas、Andy Hunt 和 Chad Fowler – 這本書是第一本關于 Ruby 的英文書籍,長期以來一直是 Ruby的標準介紹和描述。本書還首先記錄了 Ruby 核心庫和標準庫,作者將該檔案回饋給了社區。
- Ruby 問題跟蹤系統,特別是功能子跟蹤器 ——但是,請注意,不幸的是,社區在區分關于 Ruby 編程語言的票證和關于 YARV Ruby 實作的票證方面真的非常糟糕:它們都混雜在跟蹤器。
- Ruby 開發者會議的會議記錄。(同樣的問題:Ruby 和 YARV 混合在一起。)
- 郵件串列中經常討論新功能,特別是ruby??-core(英語)和ruby??-dev(日語)郵件串列。(又是同樣的問題。)
- Ruby 檔案——同樣,請注意該 檔案是從 YARV 的源代碼生成的,并且不區分 Ruby 的特性和 YARV 的特性。
- 過去,有幾次對 Ruby 規范進行形式化更改的嘗試,例如Ruby 更改請求 (RCR)和Ruby 增強建議 (REP)流程,均未成功。
- 如果一切都失敗了,您需要檢查流行的 Ruby 實作的源代碼以了解它們實際做了什么。請注意復數形式:您必須查看多個(最好是所有)實作以找出共識是什么。只看一個實作不可能告訴你你正在看的是這個特定實作的一個實作怪癖,還是 Ruby 語言的普遍認可的行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/534550.html
標籤:红宝石写时复制
上一篇:提取哈希的JSON名稱
