最近,在我的項目上運行基準測試後,我發現嚴格字節串的直接構建可能比涉及構建器的構造快一個數量級。高效創建嚴格的ByteString
例如,編碼器實現,它採用的助洗劑:
encoder :: Int64 -> Data.ByteString.ByteString
encoder =
Data.ByteString.Lazy.toStrict .
Data.ByteString.Builder.toLazyByteString .
Data.ByteString.Builder.int64BE
執行像一個比,這直接構建字節串,並且具有用於進一步優化幾種可能性差10倍:
encoder :: Int64 -> Data.ByteString.ByteString
encoder =
unpackIntBySize 8
unpackIntBySize :: (Bits a, Integral a) => Int -> a -> Data.ByteString.ByteString
unpackIntBySize n x =
Data.ByteString.pack $ map f $ reverse [0..n - 1]
where
f s =
fromIntegral $ shiftR x (8 * s)
所以我的問題是兩方面的:
瓦y是否沒有直接從
Builder
轉換爲嚴格ByteString
?這很煩人,因爲我經常必須導入Data.ByteString.Lazy
只是爲了使用toStrict
函數,因爲Data.ByteString.Builder
只公開toLazyByteString
。但是,上述經驗讓我懷疑,如果它不是有原因的。原因是我完全應用了不正確的使用模式。那麼,這確實是不正確的,是否有更好的選擇?順便說一句,我知道
Data.ByteString.Builder.Prim
,但我懷疑在上述情況下使用它會產生很大的差異。
有趣。對於我的日常工作,我假設builder - > lazy ByteString - > strict Bytestring的方式在從大量短字符串中構建一個大字符串時只會付出代價。我通常會打包。顯示從數字轉換爲嚴格的bs ...不知道它是否好。你可以發佈一些可用於衡量性能的代碼嗎?這看起來像一個有趣的問題。 – dsign
「postgresql-binary」項目有兩個分支,它們使用兩種不同的策略實現編碼器。兩者都具有編碼性能的基準。這是[一棵樹,其中的編碼器是通過直接的'ByteString'構造實現的](https://github.com/nikita-volkov/postgresql-binary/tree/911a32110cfd618e2f7d377f4acc4c8f593f9acc),這裏是[圍繞'Builder'旋轉的那個] (https://github.com/nikita-volkov/postgresql-binary/tree/2fb6954968763621cbbdb8ba8505434ec2961b9e)。 –
我覺得麻煩的是'Builder'不保持寫出結果字節串所需的字節數,儘管當你沒有做懶惰流時,這是靜態已知的(O(1))或O( N) - 丁大概價值 - 它。你可以看看'buffer-builder',看看它是否滿足你的需求。請參閱此處的討論:https://github.com/chadaustin/buffer-builder/issues/7 – jberryman