Haskell Parsec - 优化 int 解析
Haskell Parsec - Optimize int parsing
我正在使用 import Text.Parsec.Text
和 import 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 这两个库非常相似,因此迁移起来一点也不困难。如果可能的话,我会尝试进一步优化它,看看它能达到多快。
我正在使用 import Text.Parsec.Text
和 import 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 这两个库非常相似,因此迁移起来一点也不困难。如果可能的话,我会尝试进一步优化它,看看它能达到多快。