Mat*_*ner 20 haskell strict lazy-evaluation chunking bytestring
我有一个懒惰ByteString的函数,我希望有严格的ByteStrings返回列表(懒惰应该转移到输出的列表类型).
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
csVals :: L.ByteString -> [B.ByteString]
Run Code Online (Sandbox Code Playgroud)
我想因各种原因这样做,有几个lexing函数需要严格的ByteStrings,我可以保证ByteStrings输出中csVal的输出严格s 非常小.
如何在ByteString没有分块的情况下进行"严格化" ?
我想采取一个懒惰ByteString,并使一个严格ByteString包含其所有数据.
Sal*_*Sal 17
就像@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
Run Code Online (Sandbox Code Playgroud)
方法1(与@sclv相同):
toStrict1 :: BL.ByteString -> B.ByteString
toStrict1 = B.concat . BL.toChunks
Run Code Online (Sandbox Code Playgroud)
方法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)
Run Code Online (Sandbox Code Playgroud)
如果需要考虑性能,我建议您查看上面的电子邮件主题.它也有标准基准.在这些基准测试中,toStrict2比toStrict1更快.
如果有问题的惰性ByteString是<=严格ByteString的最大大小:
toStrict = fromMaybe SB.empty . listToMaybe . toChunks
Run Code Online (Sandbox Code Playgroud)
toChunks 使每个块尽可能大(除了可能是最后一个).
如果你懒惰的ByteString的大小比严格的ByteString大,那么这是不可能的:这正是lazy ByteStrings的用途.
| 归档时间: |
|
| 查看次数: |
8841 次 |
| 最近记录: |