我在 SPOJ 上的 PRIME1 问题上的尝试相当糟糕。我发现使用 ByteString确实有助于提高阅读问题文本的性能。但是,使用 ByteString 写出结果实际上比使用 Prelude 函数要慢一些。我试图弄清楚我是否做错了,或者这是预期的。
我使用 (putStrLn.show) 和 ByteString 等效项进行了三种不同的分析和计时:
- 我测试每个候选人,看它是否是素数。如果是这样,我将其添加到列表中并使用 (putStrLn . show) 将其写出来
- 我列出所有素数并使用 (putStrLn . unlines. show) 写出列表
- 我列出所有素数并使用 map (putStrLn.show) 写出列表
当您在一个函数中构建列表并在另一个函数中使用它时,我预计数字 2 和 3 的执行速度会变慢。通过在生成数字时打印它们,我避免为列表分配任何内存。另一方面,您在每次调用 putStrLn 时都会进行调用系统调用。对?所以我进行了测试,#1 实际上是最快的。
使用选项 #1 和 Prelude ([Char]) 功能实现了最佳性能。我希望我的最佳表现是使用 ByteString 的选项 #1,但事实并非如此。我只使用了惰性字节字符串,但我认为这无关紧要。会吗?
一些问题:
- 您是否希望 ByteStrings 在将一堆整数写入标准输出时表现更好?
- 我是否错过了一种生成和写出会导致更好性能的答案的方式模式?
- 如果我只是将数字写成文本,那么使用 ByteString 是否有好处?
我的工作假设是,如果您没有将它们与其他文本结合起来,那么用 ByteString 写出 Integer 会更慢。如果您将整数与 [Char] 结合使用,那么使用 ByteStrings 会获得更好的性能。即,ByteString 重写:
putStrLn $ "the answer is: " ++ (show value)
会比上面写的版本快很多。这是真的?
谢谢阅读!