문제

나는 몽고브로 가져 오기에 적합한 5 번째 칼럼에서 JSON으로 큰 TSV 파일을 만들려고 노력하고 있습니다. 특히 최상위 레벨과 최상위 키 필드 만 _id로 변경하고 싶습니다.이것은 내가 지금까지 가지고있는 것입니다. 작동하는 것 같지만 느리게 :

{-# LANGUAGE OverloadedStrings #-}

import System.Environment (getArgs)
import Data.Conduit.Binary (sourceFile, sinkFile)
import Data.Conduit
import qualified Data.Conduit.Text as CT
import qualified Data.Conduit.List as CL
import qualified Data.Text as T
import Data.Monoid ((<>))
import Data.Attoparsec.Text as APT
import Control.Applicative

main = do 
        (inputFile : outputFile : _) <- getArgs
        runResourceT $ sourceFile inputFile  
                $= CT.decode CT.utf8 $= CT.lines $= CL.map jsonify 
                $= CT.encode CT.utf8 $$ sinkFile outputFile

jsonify :: T.Text -> T.Text
jsonify = go . T.splitOn "\t"
        where 
        go (_ : _ : _ : _ : content : _) = case parseOnly keyTo_id content of
                Right res -> res <> "\n"
                _ -> ""
        go _ = ""

keyTo_id :: Parser T.Text 
keyTo_id = skipWhile(/='{') >> T.snoc <$>
        (T.cons <$> (char '{') 
                <*> (T.concat <$> many1 ( bracket 
                    <|> (string "\"key\":" >> return "\"_id\":") 
                    <|> APT.takeWhile1(\x -> x /= '{' && x /= '}' && x/= '"') 
                    <|> T.singleton <$> satisfy (/= '}')
                    )))  
        <*> char '}'        

bracket :: Parser T.Text        
bracket = T.cons <$> char '{' 
        <*> scan 1 test
     where
        test :: Int -> Char -> Maybe Int
        test 0 _ = Nothing        
        test i  '}'= Just (i-1)
        test i '{' = Just (i+1)
        test i _ = Just i
.

Profiler 58.7 %에 따르면 Bracket에서 keyto_id에서 19.6 %, 주요 17.1 %.

괄호가 일치하면 브래킷이 일치하면 브래킷이없는 용어를 변경하지 않는 더 나은 방법이 있습니다.

나는 Attoparsec-conduit를 간략하게 보았지만 해당 도서관을 사용하는 방법을 모르며 이것이 사용될 수있는 일종의 일을 알 수 없습니다.

편집 : 코드를 업데이트했습니다.데이터는 OpenLibrary.org, e.지. http:///openlibrary.org/data/ol_dump_authors_latest.txt.gz

도움이 되었습니까?

해결책

scan 기능을 사용하십시오.상태를 유지하는 문자열을 스캔 할 수 있습니다.귀하의 경우 주정부는 지금까지 발생한 개폐 중괄호의 차이입니다. 귀하의 상태가 0 일 때, 그것은 중괄호가 현재 하위 문자열 내부에서 일치 함을 의미합니다.

트릭은이 방법으로 문자열을 해체하고 재구성하지 않으므로 더 빨라야한다는 것입니다.

또한 게으른 텍스트를 사용하여 현재 알고리즘을 사용하여 일부 성능을 얻을 수 있습니다. concat 기능이보다 효율적으로 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top