約 1,000 万のキーと値のペアと、約 500,000 の一意のキーを含む 279MB のファイルがあります。キーごとにグループ化されているため (各キーは 1 回だけ書き込む必要があります)、特定のキーのすべての値がまとめられます。
私がやりたいのは、関連付けを転置し、ペアが値でグループ化されたファイルを作成し、特定の値のすべてのキーが一緒に保存されることです。
現在、Parsec を使用してペアをタプルのリストとして読み込みます(K,[V])
(遅延 IO を使用して、Parsec が入力ファイルを処理している間にストリームとして処理できるようにします)。
newtype K = K Text deriving (Show, Eq, Ord, Hashable)
newtype V = V Text deriving (Show, Eq, Ord, Hashable)
tupleParser :: Parser (K,[V])
tupleParser = ...
data ErrList e a = Cons a (ErrList e a) | End | Err e
parseAllFromFile :: Parser a -> FilePath-> IO (ErrList ParseError a)
parseAllFromFile parser inputFile = do
contents <- readFile inputFile
let Right initialState = parse getParserState inputFile contents
return $ loop initialState
where loop state = case unconsume $ runParsecT parser' state of
Error err -> Err err
Ok Nothing _ _ -> End
Ok (Just a) state' _ -> a `Cons` loop state'
unconsume v = runIdentity $ case runIdentity v of
Consumed ma -> ma
Empty ma -> ma
parser' = (Just <$> parser) <|> (const Nothing <$> eof)
タプルをに挿入してData.HashMap.Map V [K]
、関連付けを転置しようとしました:
transpose :: ErrList ParseError (K,[V]) -> Either ParseError [(V,[K])]
transpose = transpose' M.empty
where transpose' _ (Err e) = Left e
transpose' m End = Right $ assocs m
transpose' m (Cons (k,vs) xs) = transpose' (L.foldl' (include k) m vs) xs
include k m v = M.insertWith (const (k:)) v [k] m
しかし、試してみると、次のエラーが発生しました。
memory allocation failed (requested 2097152 bytes)
私が間違っていることをいくつか考えることができます:
- 2MB は少し少ないようです (私のマシンにインストールされている 2GB の RAM よりもかなり少ないです)。
- 私の問題は、アルゴリズム/データ構造に関連している可能性があります。多分私は仕事のために間違ったツールを使用していますか?
- 遅延 IO を使用しようとすると、戻ってきて噛まれる可能性があります。
今のところ(1)に傾いていますが、どうしてもわかりません。