Jak szybko może iść Go?

39

Go jest jednym z niewielu języków, które powinny działać „blisko metalu”, tzn. Jest kompilowane, statycznie wpisywane i wykonuje kod natywnie, bez maszyny wirtualnej. To powinno dać mu przewagę prędkości nad Javą, C # i podobnymi. Wygląda jednak na to, że jest za Javą (patrz: Strzelanie do języków programowania )

Zakładam, że mniej dojrzałe kompilatory są za to ogromnie odpowiedzialne, ale czy są jeszcze inne powody? Czy jest coś nieodłącznego w projekcie Go, który uniemożliwiałby jego działanie szybciej niż, powiedzmy, Java? Mam bardzo mało wyrafinowane spojrzenie na modele wykonawcze, ale wydaje się, że przynajmniej w zasadzie powinno być w stanie działać szybciej niż Java, dzięki natywnemu wykonywaniu kodu.

Greg Słodkowicz
źródło
3
Biorąc pod uwagę wystarczająco inteligentny kompilator (i / lub maszynę wirtualną i / lub kompilator JIT), dany język zawsze może iść szybciej (no cóż, istnieją fizyczne ograniczenia, ale to wszystko). Ten truizm oczywiście nikomu nie pomaga, dopóki nie ma wystarczająco inteligentnego kompilatora. Zauważ jednak, że Java ma już wystarczająco inteligentne implementacje i są niesamowicie inteligentne. Innym faktem jest to, że uruchamianie kodu ma co najmniej taki sam wpływ na wydajność środowiska wykonawczego, jak implementacja.
1
Rozumiem to, ale zastanawiałem się, czy uzasadnione jest oczekiwanie, że prędkość Go będzie pasować / wyprzedzać np. Javę, gdy kompilator dojrzewa.
Greg Słodkowicz
17
Języki programowania nie mają prędkości. Implementacje językowe też nie. Dana implementacja języka ma prędkość dla niektórych danych wejściowych, a ta prędkość może bardzo bardzo zależeć od danych wejściowych.
8
Obudź mnie ... zanim pójdziesz ... WHAM! . Przepraszam, nie mogłem się oprzeć. Tu przychodzą flagi .. tu przyjść flagi ..
Tim post
2
@delnan - A może o wiele łatwiej jest powiedzieć „Java” niż powiedzieć „Java (TM) SE Runtime Environment (kompilacja 1.6.0_25-b06) 64-bitowa maszyna wirtualna serwera Java HotSpot ™ (kompilacja 20.0-b11 , tryb mieszany) ”:-)
igouy

Odpowiedzi:

46

Jeśli chodzi o projektowanie języka, tak naprawdę nie ma nic, co mogłoby spowolnić Go w porównaniu z Javą. W rzeczywistości daje większą kontrolę nad układem pamięci struktur danych, więc w przypadku wielu typowych zadań powinno być nieco szybsze. Jednak obecny podstawowy kompilator Go, harmonogram, moduł czyszczenia pamięci, biblioteka wyrażeń regularnych i wiele innych rzeczy nie jest specjalnie zoptymalizowanych. To stale się poprawia, ale wydaje się, że nacisk kładziony jest na bycie użytecznym, prostym i wystarczająco szybkim w porównaniu do wygrywania w mikrodrukach.

W powiązanym teście Go traci duże znaczenie Java w drzewie binarnym i teście wyrażenia regularnego. Są to odpowiednio testy systemu zarządzania pamięcią i biblioteki wyrażeń regularnych. Zarządzanie pamięcią Go może być szybsze i z czasem ulegnie poprawie, a obecna standardowa biblioteka regexp jest symbolem zastępczym dla znacznie lepszej implementacji, która wkrótce nadejdzie. Przegrana na tych dwóch nie jest więc zaskakująca, aw najbliższej przyszłości margines powinien być węższy.

W przypadku testu porównawczego k-nukleotydów jest to nieco trudne do porównania, ponieważ kod Java wydaje się używać innego algorytmu. Kod Go z pewnością skorzysta z ulepszeń kompilatora, harmonogramu i alokatora, nawet jak napisano, ale ktoś musiałby przepisać kod Go, aby zrobić coś bardziej sprytnego, gdybyśmy chcieli dokładniej porównać.

Java wygrywa w teście mandelbrota, ponieważ jest to arytmetyka zmiennoprzecinkowa i pętle, i jest to świetne miejsce dla JVM do generowania naprawdę dobrego kodu maszynowego i podnoszenia rzeczy w czasie wykonywania. Dla porównania, Go ma dość prosty kompilator, który obecnie nie podnosi, nie rozwija ani nie generuje naprawdę ciasnego kodu maszynowego, więc nic dziwnego, że przegrywa. Należy jednak pamiętać, że taktowanie Javy nie liczy czasu rozruchu JVM ani tego, ile razy trzeba go uruchomić, aby JVM ładnie JITM. W przypadku długo działających programów nie jest to istotne, ale w niektórych przypadkach ma znaczenie.

Jeśli chodzi o resztę testów, Java i Go są w zasadzie „szyja w szyję”, przy czym Go zajmuje znacznie mniej pamięci, a w większości przypadków mniej kodu. Tak więc, podczas gdy Go jest wolniejszy niż Java w wielu tych testach, Java jest dość szybka, Go radzi sobie całkiem dobrze w porównaniu, a Go prawdopodobnie przyspieszy w najbliższej przyszłości.

Nie mogę się doczekać, kiedy gccgo (kompilator Go korzystający z gcc codegen) osiągnie dojrzałość; powinno to uczynić Go prawie zgodnym z C dla wielu rodzajów kodu, co będzie interesujące.

Kyle C.
źródło
2
Dobra robota, aby zrozumieć, że zawsze trzeba spojrzeć na kod źródłowy i sprawdzić, co się dzieje!
igouy
1
Informacje o czasie uruchamiania Java dla tych programów można znaleźć na stronie shootout.alioth.debian.org/help.php#java
igouy,
2
To jest dokładnie taka odpowiedź, na jaką liczyłem, dzięki!
Greg Słodkowicz
Znacznie mniejsze zużycie kodu i pamięci, lepiej kompilowany do kodu maszynowego. Wszystko to przejmuje wady prędkości.
Moshe Revah,
22
  1. Nie mówiąc nawet, które problemy zostały rozwiązane, cały test porównawczy jest bezcelowy.
  2. Zarówno JVM, jak i CLR używają JIT do tworzenia kodu maszynowego. Nie ma powodu, aby to było wolniejsze. Rozruch kosztuje tylko tyle, ile masz lat.
  3. Go został zaprojektowany do szybkiego budowania . Nie masz wielu optymalizacji czasu kompilacji i rozruchu. Do czasu uruchomienia aplikacji Java Go kompiluje własną standardową bibliotekę.

Czy Go może działać szybciej w czasie wykonywania? Tak. Czy Go będzie szybszy w czasie wykonywania? Nie wiem Być może twórcy kompilatorów dodadzą opcjonalną optymalizację kosztem czasu kompilacji. Ale nie sądzę, żeby byli tym zainteresowani. Pracują w Google.
Potrzebują języka, który pozwala na szybki rozwój i który dobrze sobie radzi w tym, co robią. Do diabła, nawet jeśli ten test porównawczy byłby wiarygodny, oznaczałoby to, że są o połowę szybsze od C i 14 razy szybsze od Pythona. To jest więcej niż wystarczająco dobre.
Sprzęt jest tani, kod jest drogi. Kod staje się coraz większy i wolniejszy w miarę inwestowania pieniędzy, sprzęt staje się tańszy i mniejszy. Chcesz języka, który nie wymaga 4 frameworków i 2000 klas, aby osiągnąć coś użytecznego.
W projekcie Go nie ma nic nieodłącznego, co czyni go powolnym. Jednak w projektantach Go jest coś nieodłącznego, co czyni go wolniejszym niż montaż: zdrowy rozsądek.

back2dos
źródło
1
Większość (wszystkich?) Zestawów JIT kompiluje się w czasie wykonywania, a nie przy pierwszym ładowaniu kodu. Ten kod maszynowy może w ogóle nie zostać wygenerowany dla niektórych kodów i może być łatwo unieważniony, np. Jeśli objsin for (obj : objs) { obj.meth() }mają za methkażdym razem różne implementacje, a JIT próbuje je wstawić. Oczywiście wszystko to jest w rzeczywistości korzystne w zwykłych przypadkach, ale nadal jest warte odnotowania.
@delnan: J8 V8 sprawdza dowolny kod przed jego wykonaniem. Ponadto LLVM został zbudowany z myślą o JITting, dlatego (z pewnym wysiłkiem oczywiście) możesz przeprowadzić dowolną optymalizację w samą porę, co w innym przypadku nastąpiłoby w czasie kompilacji. Jednak niektóre optymalizacje, takie jak analiza ucieczki, naprawdę działają tylko z JIT.
back2dos
3
>> Nawet nie mówiąc, które problemy zostały rozwiązane << Spójrz, a przekonasz się, że te strony internetowe mówią, które problemy zostały rozwiązane. W rzeczywistości znajdziesz kod źródłowy programu, buduj polecenia, uruchamiaj polecenia, wersję implementacji języka, ya da ya da ya
igouy
10

Zauważyłem również, że Go był szczególnie powolny w testach regex-dna . Russ Cox wyjaśnił, dlaczego Go nie był tak skuteczny w tym konkretnym teście . Powodem jest to, że pakiet regexp Go używa innego algorytmu dopasowywania, który działa źle w tym konkretnym teście, ale może być o wiele większy w innych testach. Również Ruby, Python i inne języki skryptowe używają implementacji C innego algorytmu dopasowywania wyrażeń regularnych .

Wreszcie gra komputerowych testów porównawczych składa się z mikro-testów, które mogą nie odzwierciedlać dokładnie wielu cech mierzonych języków, a nawet pośredniczyć w błędnych wrażeniach. Ten artykuł badawczy, niedawno opublikowany przez Google, daje dokładniejszy przegląd kilku cech językowych Go, Scala, Java i C ++ - w szczególności części „V. Performance Analysis”. W końcu Go jest prawie tak samo wymagający pamięci jak Java (81% pamięci Javy) i zużywa nawet 170% tyle pamięci, co Scala (nie mogłem znaleźć w gazecie, czy rozważono zużycie pamięci przez JVM).

Ale znowu Go jest młody i wciąż w fazie rozwoju (zmiany API)! Wkrótce pojawi się wiele ulepszeń.

Alex
źródło
3
>> Ten artykuł badawczy, niedawno opublikowany przez Google << To nie jest artykuł badawczy i nie został opublikowany przez Google. Jest to raport z doświadczenia jednego pracownika Google, zaprezentowany podczas warsztatów Scala „Scala Days 2011”.
igouy
>> może nie odzwierciedlać dokładnie wielu cech mierzonych języków, a nawet pośredniczyć w błędnych wrażeniach << Tak samo jest w przypadku programów „rozpoznawania pętli” i prawdopodobnie dotyczy każdego porównania wydajności różnych języków programowania. W rzeczywistości autor mówi: „Nie badamy żadnych aspektów mechanizmów wielowątkowości lub mechanizmów wyższego poziomu ... nie wykonujemy również ciężkich obliczeń numerycznych ...”
igouy
@igouy Na okładce można przeczytać „Google”, a wszystko, co istotne, jest opatrzone odpowiednimi odnośnikami. Dlaczego więc nie jest to „artykuł badawczy, opublikowany przez Google”, jeśli Google jest wymieniony z adresem swojej siedziby? Prace naukowe nie są domeną wyłącznie akademicką.
Alex
Na okładce można odczytać adres pocztowy, pod którym można się skontaktować z autorem, oraz adres e-mail autora. Sprawdź adres URL opublikowanego pliku pdf. Zwróć uwagę na domenę - days2011.scala-lang.org - warsztaty Scala Days „Scala Days 2011”.
igouy
1

Go jest szybszy niż Python i trochę wolniejszy niż Java. Moje szorstkie doświadczenie pokazało, że Go jest dużo (1-2 rzędy wielkości) szybszy niż Python i około 10-20% wolniejszy niż Java. Jednak Go jest nieco szybszy niż Java, jeśli jest używany z czterordzeniowym procesorem (x64). Go jest również znacznie wydajniejszy pod względem pamięci RAM.

Chciałbym dodać kilka punktów o potencjale wydajności Go w porównaniu z Javą i Pythonem. Go pozwala na więcej rzeczy, które robi C, co stale pozwala C przewyższać większość innych języków. Brakuje pamięci podręcznej, aby uniknąć kodu o wysokiej wydajności. Zmniejszenie liczby braków w pamięci podręcznej wymaga kontrolowania układu pamięci struktur danych. Go pozwala ci to zrobić. Java nie sprawia, że ​​trudniej jest uniknąć pękania pamięci i pamięci podręcznej.

W tej chwili Java zwykle działa szybciej niż Go, ponieważ Java Garbage Collector jest o wiele bardziej zaawansowany. Chociaż nie ma powodu, aby śmieciarz Go nie mógł być dużo lepszy. Generowanie kodu jest obecnie prawdopodobnie znacznie lepsze dla Javy. Go ma duży potencjał do poprawy, np. Dzięki obsłudze instrukcji wektorowych itp.

Myślę więc, że to naprawdę tylko kwestia czasu, zanim Go przejdzie poza Javę. Chociaż jak w przypadku każdego języka kod prawdopodobnie nie będzie automatycznie szybszy, gdy zostanie napisany w Go. Musisz korzystać z udogodnień, jakie daje ci język. Powiedziałbym, że Go po prostu daje więcej możliwości dostrojenia twojego kodu.

W każdym razie to tylko jedno doświadczenie programisty.

Milo Banks
źródło
4
To 8-letnie pytanie, a tania moc obliczeniowa sprawiła, że ​​stało się to praktycznie bez znaczenia. Twoja odpowiedź opiera się również na „twoich odczuciach”, a nie na twardych danych. Nie chcę cię zniechęcać, ale ...
Kayaman