Jak mogliśmy zobaczyć z The Computer Language Benchmarks Game w 2010 roku:
Jak to możliwe, pamiętając, że kompilator Go tworzy natywny kod do wykonania?
Niedojrzałe kompilatory dla Go? Czy jest jakiś nieodłączny problem z językiem Go?
EDYCJA:
Większość odpowiedzi zaprzecza samoistnej powolności języka Go, twierdząc, że problem tkwi w niedojrzałych kompilatorach.
Dlatego wykonałem własne testy do obliczania liczb Fibonacciego : algorytm iteracyjny działa w Go (freebsd, 6g) z same
prędkością jak w C (z opcją O3). Tępy rekurencyjny działa w Go 2 times
wolniej niż w C (z opcją -O3; z -O0 - to samo). Ale nie widziałem 10-krotnego upadku jak w grze wzorcowej.
java
performance
go
benchmarking
Oleg Razgulyaev
źródło
źródło
Odpowiedzi:
Kompilatory 6g i 8g nie są specjalnie optymalizujące, więc kod, który generują, nie jest szczególnie szybki.
Są zaprojektowane tak, aby same działały szybko i tworzyły kod, który jest w porządku (jest trochę optymalizacji).
gccgo
wykorzystuje istniejące przebiegi optymalizacji GCC i może zapewnić bardziej przydatne porównanie z C, ale gccgo nie jest jeszcze kompletne.Dane porównawcze prawie w całości dotyczą jakości wdrożenia. Nie mają one wiele wspólnego z językiem jako takim, z wyjątkiem tego, że implementacja spędza środowisko wykonawcze obsługując funkcje języka, których benchmark tak naprawdę nie potrzebuje. W większości języków kompilowanych wystarczająco sprytny kompilator mógłby teoretycznie usunąć to, co nie jest potrzebne, ale przychodzi moment, w którym ustawiasz demo, ponieważ bardzo niewielu prawdziwych użytkowników języka napisałoby programy, które nie używałyby tej funkcji . Usunięcie rzeczy z drogi bez ich całkowitego usuwania (np. Przewidywanie wirtualnych miejsc docelowych połączeń w skompilowanej JIT Javie) zaczyna być trudne.
FWIW, mój własny, bardzo trywialny test z Go, kiedy się temu przyglądałem (w zasadzie pętla dodawania liczb całkowitych), kod gccgo generował kod pod koniec zakresu pomiędzy
gcc -O0
igcc -O2
dla odpowiednika C. Go nie jest z natury powolne, ale kompilatory jeszcze nie wszystko. Trudno się dziwić w języku, który ma 10 minut.źródło
W następnej wersji Go FAQ powinno pojawić się coś podobnego do następującego.
A oto więcej szczegółów na temat gry Computer Benchmarks z ostatniego wątku na liście mailingowej.
Zbieranie śmieci i wydajność w gccgo (1)
Zbieranie śmieci i wydajność w gccgo (2)
Należy zauważyć, że komputerowa gra porównawcza to tylko gra. Osoby z doświadczeniem w mierzeniu wydajności i planowaniu wydajności dokładnie dopasowują się do podobnych, realistycznych i rzeczywistych obciążeń; nie grają w gry.
źródło
Moja odpowiedź nie jest tak techniczna jak u wszystkich innych, ale myślę, że nadal jest aktualna. Widziałem te same testy porównawcze w Computer Benchmarks Game, kiedy zdecydowałem się rozpocząć naukę Go. Ale szczerze uważam, że wszystkie te syntetyczne testy porównawcze są bezcelowe, jeśli chodzi o decydowanie, czy Go jest wystarczająco szybkie dla Ciebie.
Napisałem ostatnio serwer wiadomości w Pythonie przy użyciu Tornado + TornadIO + ZMQ i dla mojego pierwszego projektu w Go zdecydowałem się przepisać serwer w Go. Jak dotąd, po ustawieniu serwera do tej samej funkcjonalności co wersja Python, moje testy pokazują mi około 4,7-krotny wzrost szybkości w programie Go. Pamiętaj, że kodowałem w Go dopiero od tygodnia, a programuję w Pythonie od ponad 5 lat.
Go będzie działać szybciej, gdy będą dalej nad nim pracować, i myślę, że tak naprawdę sprowadza się to do tego, jak działa w rzeczywistej aplikacji, a nie do małych, małych obliczeniowych testów porównawczych. Dla mnie Go najwyraźniej zaowocowało wydajniejszym programem niż to, co mogłem stworzyć w Pythonie. Oto moja odpowiedź na to pytanie.
źródło
Rzeczy się zmieniły.
Myślę, że obecną poprawną odpowiedzią na twoje pytanie jest zakwestionowanie pojęcia, że idź jest wolny. W czasie twojego zapytania twój osąd był uzasadniony, ale od tego czasu go zyskał wiele uwagi pod względem wydajności. Teraz nadal nie jest tak szybki jak C, ale nie jest prawie 10 razy wolniejszy, w ogólnym sensie.
Gra z testami językowymi
W chwili pisania tego tekstu:
Chociaż cierpi brutalnie w benchmarku drzewa binarnego:
źródło
Pomimo niezbyt dobrej wydajności Go na temat wykorzystania cykli procesora, model współbieżności Go jest na przykład znacznie szybszy niż model wątków w Javie i może być porównywalny z modelem wątków C ++.
Zwróć uwagę, że w teście pierścienia wątków Go było 16x szybsze niż Java. W tym samym scenariuszu Go CSP był prawie porównywalny z C ++, ale zużywał 4x mniej pamięci.
Wielką siłą języka Go jest jego model współbieżności, komunikowanie procesów sekwencyjnych, CSP, określony przez Tony'ego Hoare'a w latach 70-tych, który jest prosty we wdrożeniu i dostosowany do bardzo współbieżnych potrzeb.
źródło
Istnieją dwa podstawowe powody, dla których Java jest szybsza niż Go i C ++ oraz może być szybsza niż C w wielu przypadkach:
1) Kompilator JIT. Może wbudowywać wywołania funkcji wirtualnych na wielu poziomach, nawet z klasami obiektowymi, w oparciu o profil środowiska wykonawczego. Nie jest to możliwe w języku kompilowanym statycznie (chociaż może pomóc nowsza ponowna kompilacja oparta na zarejestrowanym profilu). Jest to bardzo ważne w przypadku większości testów porównawczych, które obejmują powtarzalne algorytmy.
2) GC. Alokacja pamięci oparta na GC jest prawie bezpłatna w porównaniu do malloc. A „bezpłatna” kara może być amortyzowana przez cały czas działania - często jest pomijana, ponieważ program kończy działanie, zanim wszystkie śmieci będą musiały zostać zebrane.
Istnieją setki (tysiące?) Niezwykle utalentowanych programistów, dzięki którym GC / JVM jest wydajne. Myślenie, że potrafisz „kodować lepiej niż oni wszyscy”, jest głupotą. U podstaw leży problem ludzkiego ego - ludziom trudno jest zaakceptować, że przy odpowiednim przeszkoleniu przez utalentowanych ludzi komputer będzie działał lepiej niż ludzie, którzy go zaprogramowali.
Przy okazji, C ++ może być tak samo szybki jak C, jeśli nie używasz i nie korzystasz z funkcji OO, ale na początku jesteś prawie blisko programowania w C.
Co najważniejsze, „różnice prędkości” w tych testach są zwykle bez znaczenia. Koszty we / wy są o rzędy wielkości większe niż różnice w wydajności, a zatem właściwe projekty, które minimalizują koszty we / wy, zawsze wygrywają - nawet w języku interpretowanym. Bardzo niewiele systemów jest związanych z procesorem.
Na koniec, ludzie nazywają „komputerową grę porównawczą” jako „miernik naukowy”. Testy są całkowicie błędne, na przykład, jeśli przeglądasz testy Java dla nbody. Kiedy uruchamiam testy na tym samym systemie operacyjnym / sprzęcie, otrzymuję około 7,6 sekundy dla Javy i 4,7 sekundy dla C - co jest rozsądne - a nie czterokrotne spowolnienie, które zgłaszają testy. To przynęta na kliknięcia, fałszywe wiadomości, mające na celu generowanie ruchu w witrynie.
Na koniec, ostatnia uwaga ... Przeprowadziłem testy używając Go i trwało to 7,9 sekundy. Fakt, że po kliknięciu Go, porównuje ją z Javą, a po kliknięciu Java porównuje ją z C, powinien być czerwoną flagą dla każdego poważnego inżyniera.
Aby zobaczyć rzeczywiste porównanie Java, Go i C ++, zobacz https://www.biorxiv.org/content/10.1101/558056v1 alert spoilera, Java jest najlepsza pod względem surowej wydajności, a Go wychodzi na szczyt dzięki połączonemu użyciu pamięci i czas ściany.
źródło
Myślę, że często pomijanym faktem jest to, że kompilacja JIT może być> kompilacją statyczną, szczególnie w przypadku funkcji lub metod związanych z późnym wiązaniem (runtime). Hotspot JIT decyduje w RUNTIME, które metody wbudować, może nawet dostosować układ danych do rozmiaru / architektury pamięci podręcznej procesora, na którym obecnie działa. Ogólnie C / C ++ może nadrobić zaległości (i ogólnie nadal będzie działać lepiej), mając bezpośredni dostęp do sprzętu. W przypadku Go rzeczy mogą wyglądać inaczej, ponieważ są bardziej wysokopoziomowe w porównaniu do C, ale obecnie brakuje systemu / kompilatora optymalizacji czasu wykonywania. Mój instynkt podpowiada mi, że Go może być szybsze niż Java, ponieważ Go nie wymusza tak bardzo podążania za wskaźnikami i zachęca do lepszej struktury danych, lokalność + wymaga mniejszej alokacji.
źródło
W rzeczywistości Go jest nie tylko eleganckie i wydajne w czasie projektowania, ale także bardzo wydajne w czasie wykonywania. Kluczem jest użycie odpowiedniego systemu operacyjnego, czyli LINUX. Wyniki profilowania wydajności w Windows i Mac OS są, z braku lepszego słowa, o jeden lub dwa rzędy wielkości gorsze.
źródło
pod linuxem środowisko uruchomieniowe go jest super szybkie, doskonale porównywalne z c / c ++. środowisko uruchomieniowe go pod windows i unix nie są w tej samej lidze
Porównanie z Javą nie jest tak ważne, go jest przeznaczone zarówno do tworzenia systemów, jak i aplikacji (ponieważ java jest bardziej jak niebieski kołnierz tylko do tworzenia aplikacji). nie będzie wprowadzać szczegółów, ale kiedy rzeczy takie jak kubernetes są zapisywane w go, zdajesz sobie sprawę, że nie jest to zabawka przyjazna dla konsultantów przedsiębiorstwa
Nie pamiętam, żeby google wspominało choć raz o kompromisie, o którym pan mówi. go jest dobrze zaprojektowany, prosty, elegancki i wydajny do projektowania programów na poziomie systemu i aplikacji, ma wskaźniki, wydajną alokację i zwalnianie pamięci, pozwala uniknąć komplikacji wynikających z tak łatwego do pominięcia dziedziczenia implementacji, dając ci wspólne procedury i inne nowoczesne sposoby pisania aplikacji o wysokiej wydajności w czasie i budżecie. znowu, go jest super szybki pod Linuksem, do czego został zaprojektowany (bardzo się cieszę, że tak)
źródło
Zarówno Java, jak i C są bardziej przejrzyste dzięki swoim definicjom danych i metod (funkcji). C jest typowany statycznie, a Java jest mniej podatna na model dziedziczenia. Oznacza to, że sposób obsługi danych jest prawie określony podczas kompilacji.
Go jest bardziej niejawny z definicjami danych i funkcji. Wbudowane funkcje mają bardziej ogólny charakter, a brak hierarchii typów (takich jak Java lub C ++) powoduje, że Go ma niekorzystny wpływ na szybkość.
Pamiętaj, że celem Google dla języka Go jest uzyskanie akceptowalnego kompromisu między szybkością wykonywania a szybkością kodowania. Myślę, że trafiają w dobry słodki punkt we wczesnych próbach, a sytuacja poprawi się tylko wtedy, gdy wykonasz więcej pracy.
Jeśli porównasz Go z bardziej dynamicznie wpisywanymi językami, których główną zaletą jest szybkość kodowania, zobaczysz przewagę szybkości wykonywania Go. Go jest 8 razy szybsze niż Perl i 6 razy szybsze niż Ruby 1.9 i Python 3 w tych testach porównawczych, których użyłeś.
W każdym razie, lepszym pytaniem jest: Go to dobry kompromis między łatwością programowania a szybkością wykonywania? Moja odpowiedź brzmi: tak i powinno być lepiej.
źródło