haskell lazy-evaluation strict bytestring chunking

haskell - Convertir un ByteString perezoso a un ByteString estricto



lazy-evaluation chunking (5)

Como @sclv dijo en los comentarios anteriores, un bytestring perezoso es solo una lista de bytestrings estrictos. Hay dos enfoques para convertir la ByteString perezosa en estricta (fuente: discusión de la lista de correo de haskell sobre cómo agregar a la función de Sttrict ) - código relevante del hilo de correo electrónico a continuación:

Primero, las bibliotecas relevantes:

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

Enfoque 1 (igual que @sclv):

toStrict1 :: BL.ByteString -> B.ByteString toStrict1 = B.concat . BL.toChunks

Enfoque 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)

Si el rendimiento es una preocupación, recomiendo revisar el hilo de correo electrónico anterior. Tiene criterio de referencia también. toStrict2 es más rápido que toStrict1 en esos puntos de referencia.

Tengo una función que toma un ByteString lento , que deseo tener listas de retorno de ByteStrings estrictos (la pereza debe transferirse al tipo de lista de la salida).

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

Quiero hacer esto por varias razones, varias funciones lexing requieren estrictas ByteString s, y puedo garantizar que las estrictas ByteString en la salida de csVal s anteriores son muy pequeñas.

¿Cómo hago para " ByteString " las ByteString s sin chunking ?

Actualización0

Quiero tomar una ByteString perezosa y hacer una ByteString estricta que contenga todos sus datos.


Data.ByteString.Lazy.Char8 ahora tiene las funciones ToStrict y fromStrict.



Si el ByteString perezoso en cuestión es <= el tamaño máximo de un ByteString estricto:

toStrict = fromMaybe SB.empty . listToMaybe . toChunks

toChunks hace que cada parte sea lo más grande posible (excepto posiblemente la última).

Si el tamaño de su ByteString perezoso es mayor que lo que puede ser un ByteString estricto, entonces esto no es posible: eso es exactamente para lo que son los ByteStrings perezosos.


También puedes usar blaze-builder para construir ByteString estricta desde la perezosa

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

Debe ser eficaz.