Los tipos de cadenas Haskell comúnmente recomendados parecen ser ByteString o Text. A menudo trabajo con una gran cantidad de cadenas cortas (tamaño de palabras en inglés), y generalmente necesito almacenarlas en una tabla de búsqueda como Data.Map. En muchos casos encuentro que en este escenario, una tabla de cadenas puede ocupar menos memoria que una tabla de ByteStrings. Datos no compartidos. Los vectores de Word8 también son (mucho) más compactos que ByteStrings.Cadenas de memoria eficiente en Haskell
¿Cuál es la mejor práctica cuando se necesita almacenar y comparar grandes cantidades de cadenas pequeñas en Haskell?
continuación he tratado de condensar un caso problemático particular, en un pequeño ejemplo:
import qualified Data.ByteString.Lazy.Char8 as S
import qualified Data.ByteString as Strict
import qualified Data.Map as Map
import qualified Data.Vector.Unboxed as U
import qualified Data.Serialize as Serialize
import Control.Monad.State
main = putStr
. unlines . map show . flip evalState (0,Map.empty)
. mapM toInt
. S.words
=<<
S.getContents
toInt x = do
let x' =
U.fromList . Strict.unpack . -- Comment this line to increase memory usage
Serialize.encode $ x
(i,t) <- get
case Map.lookup x' t of
Just j -> return j
Nothing -> do
let i' = i + (1::Int)
put (i', Map.insert x' i t)
return i
Cuando ejecuto esto en un archivo que contiene alrededor de 400.000 palabras de texto Inglés, la versión con teclas ByteString estrictas utiliza alrededor de 50 MB memoria, la que tiene vectores de Word8 usa 6MB.
¿Para qué estás usando esas cadenas? ¿Es algún tipo de diccionario? – ARRG
¿Puedes dar algún ejemplo de código en el que ByteStrings ocupe más memoria que Cadenas o memoria "mucho más" que los vectores de Word8? No entiendo por qué sería ese el caso a menos que estés haciendo algo extraño. – shang
@shang: me imagino que esto sucederá si cometes el error de comparar el tamaño de un mapa lleno de estrictas ByteStrings con un mapa que contiene secuencias de cadenas. Aunque más detalles serían útiles. Un programa de prueba breve que demuestre el problema sería especialmente bueno. – hammar