Tim*_*rry 24 io performance haskell bytestring
我对SPOJ上的PRIME1问题的尝试一直很糟糕.我发现使用ByteString 实际上有助于在问题文本中阅读的性能.但是,使用ByteString写出结果实际上比使用Prelude函数稍慢.我想知道我做错了,或者这是否是预期的.
我使用(putStrLn.show)和ByteString等效三种不同的方式进行了分析和计时:
我期望数字2和3执行速度较慢,因为您在一个函数中构建列表并在另一个函数中使用它.通过在生成数字时打印数字,我避免为列表分配任何内存.另一方面,每次调用putStrLn时都要进行一次调用系统调用.对?所以我测试了,#1实际上是最快的.
使用选项#1和Prelude([Char])函数实现了最佳性能.我期望我的最佳表现是ByteString的选项#1,但事实并非如此.我只使用懒惰的ByteStrings,但我认为这不重要.是吗?
一些问题:
我的工作假设是,如果你没有将它们与其他文本组合,用ByteString写出Integer是比较慢的.如果您将Integers与[Char]结合使用,那么使用ByteStrings可以获得更好的性能.即,ByteString重写:
putStrLn $ "the answer is: " ++ (show value)
Run Code Online (Sandbox Code Playgroud)
将比上面写的版本快得多.这是真的?
谢谢阅读!
Don*_*art 21
使用字节串进行批量输入通常更快,因为数据密集,从磁盘到内存的数据更少.
然而,将数据写为输出则略有不同.通常,您要序列化结构,生成许多小写入.因此,在这种情况下,字节串的密集,批量写入对您没有多大帮助.即使是常规Strings
也会合理地增加产量.
但是,一切都不会丢失.我们可以通过在内存中有效地构建字节串来恢复快速批量写入.这种方法由各种*-builder
包采用:
我们不是将值转换为许多微小的字节串,而是一次一个地写出来,而是将转换流转换为不断增长的缓冲区,然后将缓冲区写入一个大块.与字符串IO相比,这会导致更少的IO开销和性能改进(通常是显着的).
这种方法是采取在Haskell例如Web服务器,或者有效的HTML系统,杀出.
此外,即使使用批量写入,性能也取决于类型和字节串之间的任何转换函数的效率.因为Integer
,您可能只是将内存中的位模式复制到输出,或者通过一些低效的解码器.因此,您有时需要考虑一下您正在使用的编码函数的质量,而不仅仅是使用Char/String还是bytestring IO.