[ODPOWIEDŹ] Go nie buforuje stdout. Przejście do wersji buforowanej i ręczne spłukiwanie znacznie przybliża to, czego można się spodziewać. Unikanie fmt sprawia, że działa tak szybko, jak chcesz.Program FizzBuzz wydaje się powolny: dlaczego?
Próbuję napisać program FizzBuzz w 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)
}
}
Po uruchomieniu go dla liczb od 1 do miliona, ukończenie zajmuje mniej niż sekundę. Kiedy piszę program równoważny w C, Rust, Haskell lub Python, zajmuje to od pół sekundy (Python) do zera sekund (Rust i Haskell).
Czy można się tego spodziewać, czy też brakuje mi Go-fu? Dlaczego wydaje się wolniej niż inne języki?
[EDIT]
Biegając z profilera sugerowane przez Robert Harvey.
Wygląda na to, że 100% czasu spędzamy w fmt. (* Fmt) .fmt_complex, który, jak przypuszczam, jest powiązany z Println (?). Wypróbowałem również program z strconv.Itoa zamiast fmt.Sprint i otrzymałem niewielki wzrost wydajności (~ 0.2s), ale te same podstawowe wyniki.
Czy drukowanie jest powolne, a jeśli tak, dlaczego?
[Edycja]
Na jgritty równoważnej Pythonowego programu i czas podawania. Interesuje mnie, dlaczego drukowanie jest wolniejsze? Czy robię coś poza kulisami, o których nie wiem?
$ 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
http://blog.golang.org/profiling-go-programs –
Zauważ, że Haskell jest językiem leniwy; prawdopodobnie nie ocenia twoich wyników, dopóki nie poprosisz o wynik. To samo najprawdopodobniej dotyczy Rust. –
Może zacząć działać dłużej niż w innych językach? Co jeśli próbowałeś, aby program przetwarzał więcej danych, więc uruchomienie trwa 10 sekund? –