Haskell Parsec - 优化 int 解析

Haskell Parsec - Optimize int parsing

我正在使用 import Text.Parsec.Textimport Text.Parsec.Char 来解析一些包含整数的数据。我正在使用以下代码来解析整数。

p_int :: Parser Int
p_int = read <$> ((++) <$> option "" (string "-") <*> many1 digit)

我分析了我的程序,发现上面的代码片段占用了 >90% 的执行时间。如何优化上面的代码?

我发现 Text.ParserCombinators.Parsec.Number 模块包含一个 int 函数来解析整数。但是,它的类型是 int :: Integral i => CharParser st i,它与我正在使用的基于 Text 的解析器不兼容,如下面的错误所示。

   • Couldn't match type ‘[Char]’ with ‘Text’
      Expected type: Parser Int
        Actual type: Text.ParserCombinators.Parsec.Char.CharParser () Int

更新 我用 Text.Parsec.String 替换了 Text.Parsec.Text,并用 Text.ParserCombinators.Parsec.Number 中的 int 替换了我的 int 解析函数。这将执行时间缩短了约 40%。但性能仍然比 Python 差。分析表明 int 解析消耗了大约 80% 的时间。这是否意味着秒差距只是慢?

COST CENTRE    MODULE                               SRC                                                       %time %alloc

sign           Text.ParserCombinators.Parsec.Number Text/ParserCombinators/Parsec/Number.hs:277:1-73           34.4   39.8
number         Text.ParserCombinators.Parsec.Number Text/ParserCombinators/Parsec/Number.hs:(321,1)-(323,18)   26.7   27.5
numberValue    Text.ParserCombinators.Parsec.Number Text/ParserCombinators/Parsec/Number.hs:(327,1)-(328,74)   10.2    6.7
zeroNumber     Text.ParserCombinators.Parsec.Number Text/ParserCombinators/Parsec/Number.hs:(300,1)-(301,56)    6.0   10.0
...

....

int                Text.ParserCombinators.Parsec.Number Text/ParserCombinators/Parsec/Number.hs:273:1-17         499          0    1.4    1.6    79.5   86.5

我用 Attoparsec 替换了 Parsec,并且没有任何优化,现在速度提高了 80%。 "total alloc" 也从超过 3GB 下降到 507MB。

API 这两个库非常相似,因此迁移起来一点也不困难。如果可能的话,我会尝试进一步优化它,看看它能达到多快。