[答案] Go没有缓冲标准输出。切换到缓冲版本并手动刷新使其更接近您的预期。避免fmt使其运行速度尽可能快。
我试图在Go中编写FizzBuzz程序。
func main() {
for i := 1; i <= 1000000; i++ {
fmt.Println(fizzbuzz(i))
}
}
func fizzbuzz(n int) string {
fizzy := n%3 == 0
buzzy := n%5 == 0
switch {
case fizzy && buzzy:
return "FizzBuzz"
case fizzy:
return "Fizz"
case buzzy:
return "Buzz"
default:
return fmt.Sprint(n)
}
}
当我为1到100万的数字运行它时,只需不到一秒钟即可完成。 当我用C,Rust,Haskell或Python编写等效程序时,需要半秒(Python)到零秒(Rust和Haskell)。
这是预期的,还是我错过了一些Go-fu?为什么go似乎比其他语言慢?
[编辑]
按照Robert Harvey的建议运行探查器。
看起来100%的时间用在fmt。(* fmt).fmt_complex中,我猜测它与Println(?)有关。还试用了strconv.Itoa而不是fmt.Sprint的程序,我得到了轻微的性能提升(~0.2s),但基本结果相同。
印刷是否缓慢,如果是这样,为什么?
[编辑]
对于jgritty,等效的Python程序和时序。 我对打印速度慢的原因感兴趣?我不知道在幕后做什么吗?
$ cat fizzbuzz.py
def fizzbuzz(n):
fizzy = n%3 == 0
buzzy = n%5 == 0
if fizzy and buzzy:
return "FizzBuzz"
elif fizzy:
return "Fizz"
elif buzzy:
return "Buzz"
else:
return ("%u" % n)
def main():
for i in range(1, 10**6):
print(fizzbuzz(i))
main()
$ time pypy3 fizzbuzz.py >/dev/null
real 0m0.579s
user 0m0.545s
sys 0m0.030s
答案 0 :(得分:6)
标准输出在Python和C中缓冲,但不是Go。缓冲输出以进行苹果对苹果的比较。这几乎把我的笔记本电脑上的时间缩短了一半。
import (
"bufio"
"fmt"
"os"
)
func main() {
w := bufio.NewWriter(os.Stdout)
for i := 1; i <= 1000000; i++ {
fmt.Fprintln(w, fizzbuzz(i))
}
w.Flush()
}
取消使用fmt package进行其他改进:
package main
import (
"bufio"
"os"
"strconv"
)
func main() {
w := bufio.NewWriter(os.Stdout)
for i := 1; i <= 1000000; i++ {
w.WriteString(fizzbuzz(i))
w.WriteString("\n")
}
w.Flush()
}
func fizzbuzz(n int) string {
fizzy := n%3 == 0
buzzy := n%5 == 0
switch {
case fizzy && buzzy:
return "FizzBuzz"
case fizzy:
return "Fizz"
case buzzy:
return "Buzz"
default:
return strconv.Itoa(n)
}
}