Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 何时使用ByteString,何时不使用?_Haskell_Io_Performance_Bytestring - Fatal编程技术网

Haskell 何时使用ByteString,何时不使用?

Haskell 何时使用ByteString,何时不使用?,haskell,io,performance,bytestring,Haskell,Io,Performance,Bytestring,我在SPOJ上的PRIME1问题上做了相当糟糕的尝试。我发现使用ByteString确实有助于提高阅读问题文本的性能。然而,使用ByteString写出结果实际上比使用Prelude函数稍微慢一些。我在试图弄清楚我是做错了,还是这是意料之中的 我使用(putStrLn.show)和ByteString等效程序以三种不同的方式进行了评测和计时: 我对每个候选人进行测试,看是否 这是最好的。如果是,我会将其添加到列表中 并用(putStrLn)写出。 (节目) 我列出所有素数 并使用 (putStr

我在SPOJ上的PRIME1问题上做了相当糟糕的尝试。我发现使用ByteString确实有助于提高阅读问题文本的性能。然而,使用ByteString写出结果实际上比使用Prelude函数稍微慢一些。我在试图弄清楚我是做错了,还是这是意料之中的

我使用(putStrLn.show)和ByteString等效程序以三种不同的方式进行了评测和计时:

  • 我对每个候选人进行测试,看是否 这是最好的。如果是,我会将其添加到列表中 并用(putStrLn)写出。 (节目)
  • 我列出所有素数 并使用 (putStrLn.unlines.show)
  • 我列出所有素数 并使用 地图(putStrLn.show)
  • 当您在一个函数中构建列表并在另一个函数中使用它时,我希望数字2和3的执行速度较慢。通过在生成数字时打印这些数字,我可以避免为列表分配任何内存。另一方面,每次调用putStrLn时,您都要进行一次调用系统调用。对吗?所以我测试了一下#1实际上是最快的

    选项#1和前奏([Char])功能实现了最佳性能。我希望我的最佳性能是带有ByteString的选项1,但事实并非如此。我只使用了lazy ByteStrings,但我认为这并不重要。会吗

    一些问题:

    • 你希望ByteStrings能 在写一大堆文章时表现更好 整数到标准输出
    • 我是不是错过了一个模式 生成并写出答案 这将导致更好的结果 表演
    • 如果我只是把数字写成 文本,如果有的话,什么时候有 使用ByteString的好处是什么
    我的工作假设是,如果不将整数与其他文本组合,则使用ByteString写出整数的速度较慢。如果将整数与[Char]相结合,那么使用bytestring可以获得更好的性能。即,ByteString重写:

    putStrLn $ "the answer is: " ++ (show value)
    
    将比上面写的版本快得多。这是真的吗

    谢谢你的阅读

    使用ByTestRing进行大容量输入通常更快,因为数据密集,所以从磁盘到内存的随机数据更少

    但是,将数据写入输出有点不同。通常,您正在序列化一个结构,生成许多小的写操作。因此,在这种情况下,bytestring的密集、大容量写入对您没有多大帮助。即使是常规的
    字符串
    也可以在增量输出时正常工作

    然而,一切都没有失去。通过在内存中高效地构建ByTestRing,我们可以恢复快速的批量写入。各种
    *-builder
    软件包都采用了这种方法:

    我们不是将值转换成许多微小的bytestring,然后一次写出一个,而是将转换流到一个不断增长的缓冲区中,然后将该缓冲区写入一个大的块中。与字符串IO相比,这会大大减少IO开销,并提高性能(通常是显著的)

    这种方法是由Haskell中的Web服务器或高效的HTML系统采用的


    此外,即使是大容量写入,性能也将取决于类型和bytestring之间的转换函数的效率。对于
    Integer
    ,您可以简单地将内存中的位模式复制到输出,或者通过一些低效的解码器。因此,您有时需要考虑正在使用的编码函数的质量,而不仅仅是使用Char/String还是bytestring IO。

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

    您能告诉我上面提到的一个库的核心吗。即,将转换流化为不断增长的缓冲区的部分?我不熟悉这些库的内部结构。Text.Blaze.Renderer.UTF8中的renderHtml就是一个例子吗?例如,在二进制文件中,a是一个连续函数,异步更新可变缓冲区。