[英]Convert a Lazy ByteString to a strict ByteString
我有一個帶有惰性ByteString
的函數,我希望返回嚴格的ByteStrings
列表(懶惰應該轉移到輸出的列表類型)。
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
csVals :: L.ByteString -> [B.ByteString]
我想這樣做是出於各種原因, 幾個lexing函數需要嚴格的ByteString
,而且我可以保證輸出的嚴格ByteString
在csVal
s的輸出中非常小。
如何在沒有分塊的情況下對“ ByteString
”進行“嚴格化”?
我想采用一個Lazy ByteString
,並生成一個包含其所有數據的嚴格ByteString
。
該bytestring
包現在出口一toStrict
功能:
這可能不是你想要的,但它肯定回答了這篇文章標題中的問題:)
就像@sclv在上面的注釋中所說的那樣,lazy bytestring只是一個嚴格的字節串列表。 有兩種方法可以將惰性ByteString轉換為strict(源: haskell郵件列表討論添加到嚴格函數 ) - 來自以下電子郵件線程的相關代碼:
一,相關圖書館:
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as BI
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Internal as BLI
import Foreign.ForeignPtr
import Foreign.Ptr
方法1(與@sclv相同):
toStrict1 :: BL.ByteString -> B.ByteString
toStrict1 = B.concat . BL.toChunks
方法2:
toStrict2 :: BL.ByteString -> B.ByteString
toStrict2 BLI.Empty = B.empty
toStrict2 (BLI.Chunk c BLI.Empty) = c
toStrict2 lb = BI.unsafeCreate len $ go lb
where
len = BLI.foldlChunks (\l sb -> l + B.length sb) 0 lb
go BLI.Empty _ = return ()
go (BLI.Chunk (BI.PS fp s l) r) ptr =
withForeignPtr fp $ \p -> do
BI.memcpy ptr (p `plusPtr` s) (fromIntegral l)
go r (ptr `plusPtr` l)
如果需要考慮性能,我建議您查看上面的電子郵件主題。 它也有標准基准。 在這些基准測試中,toStrict2比toStrict1更快。
如果有問題的惰性ByteString是<=嚴格ByteString的最大大小:
toStrict = fromMaybe SB.empty . listToMaybe . toChunks
toChunks
使每個塊盡可能大(除了可能是最后一個)。
如果你懶惰的ByteString的大小比嚴格的ByteString大,那么這是不可能的:這正是lazy ByteStrings的用途。
您還可以使用blaze-builder從惰性構建嚴格的ByteString
toStrict :: BL.ByteString -> BS.ByteString
toStrict = toByteString . fromLazyByteString
它必須是有效的。
Data.ByteString.Lazy.Char8現在具有toStrict和fromStrict函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.