Я пытаюсь написать код для выполнения следующей простой задачи в Haskell: поиск этимологий слов с использованием этого словаря, хранящихся в виде большого файла TSV (http://www1.icsi.berkeley.edu/~demelo/etymwn/). Я думал, что я проанализирую (с attoparsec) файл tsv на Карте, который я мог бы использовать для эффективного поиска этимологий, как требуется (и делать некоторые другие вещи).эффективно читает большой файл на карте
Это был мой код:
{-# LANGUAGE OverloadedStrings #-}
import Control.Arrow
import qualified Data.Map as M
import Control.Applicative
import qualified Data.Text as DT
import qualified Data.Text.Lazy.IO as DTLIO
import qualified Data.Text.Lazy as DTL
import qualified Data.Attoparsec.Text.Lazy as ATL
import Data.Monoid
text = do
x <- DTLIO.readFile "../../../../etymwn.tsv"
return $ DTL.take 10000 x
--parsers
wordpair = do
x <- ATL.takeTill (== ':')
ATL.char ':' *> (ATL.many' $ ATL.char ' ')
y <- ATL.takeTill (\x -> x `elem` ['\t','\n'])
ATL.char '\n' <|> ATL.char '\t'
return (x,y)
--line of file
line = do
a <- (ATL.count 3 wordpair)
case (rel (a !! 2)) of
True -> return . (\[a,b,c] -> [(a,c)]) $ a
False -> return . (\[a,b,c] -> [(c,a)]) $ a
where rel x = if x == ("rel","etymological_origin_of") then False else True
tsv = do
x <- ATL.many1 line
return $ fmap M.fromList x
main = (putStrLn . show . ATL.parse tsv) =<< text
Он работает для небольших объемов ввода, но быстро растет слишком неэффективно. Я не совсем понимаю, где проблема, и вскоре понял, что даже тривиальные задачи, такие как просмотр последнего символа файла, слишком долгое время, когда я пытался, например. с
foo = fmap DTL.last $ DTLIO.readFile "../../../../etymwn.tsv
Итак, мои вопросы: в чем основные вещи, которые я делаю неправильно, с точки зрения подхода и исполнения? Любые советы для большего количества Haskelly/лучшего кода?
Спасибо,
Рувим
Прокомментировал код? https://nikita-volkov.github.io/profiling-cabal-projects/ https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/prof-heap.html http://book.realworldhaskell.org/read/profiling-and-optimization.html – grwp
Если файл, который вы читаете, слишком велик, хорошим вариантом сокращения времени запуска программы является перемещение содержимого этого файла в базу данных (встроенный или нет). После индексирования в базе данных случайные поисковые запросы могут выполняться напрямую, не сначала считывая файл. – fgv
В дополнение к профилированию я предлагаю ознакомиться с этим кратким руководством по соображениям производительности: https://hackage.haskell.org/package/attoparsec-0.13.0.1/docs/Data-Attoparsec-ByteString.html#g:3 – erdeszt