[ANSWER] Go does not buffer stdout. Switching to the buffered version and manual cleaning brings it closer to what you expect. Avoiding fmt makes it work as fast as you like.
I am trying to write a FizzBuzz program in Go.
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) } }
When I run it for numbers from 1 to a million, it takes only one second to complete. When I write an equivalent program in C, Rust, Haskell or Python, it takes from one and a half seconds (Python) to zero seconds (Rust and Haskell).
Is this expected, or am I missing some go-fu? Why does the move look slower than other languages?
[EDIT]
Work with the profiler, as suggested by Robert Harvey.
It seems like 100% of the time is spent on fmt. (* fmt) .fmt_complex, which I assume is associated with Println (?). I also tried the program with strconv.Itoa instead of fmt.Sprint, and I got a slight performance increase (~ 0.2s), but the same basic results.
This is a slow print, and if so, why?
[EDIT]
For jgritty, the equivalent Python program and timings. I am wondering why printing is slower? Am I doing something backstage that I donβt know about?
$ 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
performance go fizzbuzz
Joseph
source share