什么时候使用ByteString,什么时候不使用?

我对SPOJ上的PRIME1问题做了相当差的尝试。我发现使用ByteString 真的帮助阅读问题文本的性能。但是,使用ByteString写出结果实际上比使用Prelude函数稍慢。我试图弄清楚我是否做错了,或者如果这是预期的。什么时候使用ByteString,什么时候不使用?

我使用进行分析和定时(putStrLn.show)和字节串当量三种不同的方法:

  1. 我测试每个候选,以确定它是 素。如果是的话,我把它添加到列表 并将其与写出来(putStrLn。 显示)
  2. 我让所有的素数 的列表,并写出使用 列表(putStrLn。unlines。秀)
  3. 我让所有的素数 的列表,并写出使用 地图(putStrLn。秀)

我的预期数字2和3,你在一个函数建立一个列表,并在另一个消费它来执行较慢的列表。通过打印我生成的数字,我避免为列表分配任何内存。另一方面,您每次调用putStrLn时都会进行一次呼叫系统调用。对?所以我测试了#1实际上是最快的。

使用选项#1和Prelude([Char])功能可以获得最佳性能。我预计我的最佳性能是使用ByteString的选项#1,但事实并非如此。我只使用懒惰的ByteStrings,但我认为这不重要。会吗?

一些问题:

  • ,你会想到字节串到 写一堆 整数到stdout有更好的表现?
  • 我错过了一个方式 生成并写出答案 这将导致更好的 表现?
  • 如果我只写出 文本的数字,那么在使用ByteString时有没有 好处?

我的工作假设是,写出Integer与ByteString比较慢,如果你没有将它们与其他文本相结合。如果您将整数与[Char]组合在一起,那么您可以使用ByteStrings获得更好的性能。即,ByteString重写为:

putStrLn $ "the answer is: " ++ (show value) 

会比上面写的版本快得多。这是真的?

感谢您的阅读!

回答:

做批量输入通常用bytestrings更快,因为数据很密集,只有较少的数据从磁盘转移到内存中。

写数据为输出但是,有点不同。通常情况下,你正在序列化一个结构,产生许多小写。因此,在这种情况下,字节串的密集写入操作对你来说帮助不大。即使是经常性的Strings也会在增量输出时合理地执行。

但是,一切都不会丢失。我们可以通过有效地在内存中构建字节字符来恢复快速批量写入。这种方法是采取各种*-builder包:

  • binary
  • blaze-builder

不是值转换为许多微小的字节串,并在同一时间写出来一个,我们流的转换进入一个不断增长的缓冲区,然后将这个缓冲区写入一个大块。这导致IO开销少得多,并且通过字符串IO提高了性能(通常很重要)。

这种方法是由例如, Haskell的网络服务器或高效的HTML系统blaze。

此外,即使使用批量写入,性能也取决于您的类型和字节串之间的任何转换函数的效率。对于Integer,您可能简单地将内存中的位模式复制到输出中,或者转而使用一些效率低下的解码器。因此,您有时必须考虑一下您使用的编码函数的质量,而不仅仅是使用Char/String还是字符串IO。

回答:

请注意,性能不是ByteStringString之间的主要区别。前者用于二进制数据,后者用于Unicode文本。如果您有二进制数据,请使用ByteString,如果您有Unicode文本,请使用text package中的Text类型。

以上是 什么时候使用ByteString,什么时候不使用? 的全部内容, 来源链接: utcz.com/qa/265913.html

回到顶部