23

lazyByteStringを受け取る関数があり、 strictByteStringsのリストを返す必要があります (遅延は出力のリスト型に転送する必要があります)。

import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
csVals :: L.ByteString -> [B.ByteString]

さまざまな理由でこれを行いたいのですが、いくつかの字句解析関数では strict が必要であり、上記の s の出力で出力された strictが非常に小さいByteStringことを保証できます。ByteStringcsVal

それらをチャンクByteStringせずに「厳密化」するにはどうすればよいですか?

Update0

Lazy を取り、そのすべてのデータを含むByteString1 つの strict を作成したいと思います。ByteString

4

5 に答える 5

39

bytestringパッケージは関数をエクスポートするようになりましたtoStrict:

http://hackage.haskell.org/packages/archive/bytestring/0.10.2.0/doc/html/Data-ByteString-Lazy.html#v:toStrict

これはまさにあなたが望むものではないかもしれませんが、この投稿のタイトルの質問に確実に答えます:)

于 2012-11-29T18:16:48.257 に答える
17

上記のコメントで @sclv が述べたように、遅延バイト文字列は厳密なバイト文字列の単なるリストです。lazy ByteString を strict に変換するには 2 つの方法があります (ソース: haskell メーリング リストでの toStrict 関数の追加に関するディスカッション) - 以下の電子メール スレッドからの関連コード:

まず、関連するライブラリ:

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 よりも高速です。

于 2011-12-18T15:27:52.027 に答える
5

問題の遅延 ByteString が <= 厳密な ByteString の最大サイズである場合:

toStrict = fromMaybe SB.empty . listToMaybe . toChunks

toChunks各チャンクを可能な限り大きくします (おそらく最後のチャンクを除く)。

怠惰な ByteString のサイズが厳密な ByteString のサイズよりも大きい場合、これは不可能です。それがまさに怠惰な ByteString の目的です。

于 2011-10-19T06:30:42.433 に答える
2

Data.ByteString.Lazy.Char8 に toStrict および fromStrict 関数が追加されました。

于 2017-10-09T22:22:09.633 に答える
1

blaze-builderを使用して、lazy から厳密な ByteString を構築することもできます

toStrict :: BL.ByteString -> BS.ByteString
toStrict = toByteString . fromLazyByteString

それは効果的でなければなりません。

于 2013-04-06T16:54:54.783 に答える