[回答] Go は stdout をバッファリングしません。バッファリングされたバージョンに切り替えて手動でフラッシュすると、期待するものにはるかに近づきます。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 万までの数値に対して実行すると、完了するまでに 1 秒もかかりません。C、Rust、Haskell、または Python で同等のプログラムを作成すると、0.5 秒 (Python) から 0 秒 (Rust と Haskell) までかかります。
これは当然のことでしょうか、それとも Go-fu が不足しているのでしょうか? go が他の言語よりも遅いように見えるのはなぜですか?
[編集]
Robert Harvey によって提案されたプロファイラーで実行します。
時間の 100% が fmt.(*fmt).fmt_complex に費やされているように見えますが、これは Println(?) に関連していると推測しています。また、fmt.Sprint の代わりに strconv.Itoa を使用してプログラムを試してみたところ、パフォーマンスがわずかに向上しましたが (~0.2 秒)、基本的な結果は同じでした。
遅いのは印刷ですか? もしそうなら、それはなぜですか?
[編集]
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