【发布时间】:2014-11-26 19:09:29
【问题描述】:
[ANSWER] 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
【问题讨论】:
-
请注意,Haskell 是一种惰性语言;在您实际要求输出之前,它可能不会评估您的结果。 Rust 很可能也是如此。
-
也许 go 的启动时间比其他语言要长?如果您尝试让程序处理更多数据以使其运行大约需要 10 秒呢?
标签: performance go fizzbuzz