Wygląda na to, że zadajesz dwa dość różne pytania:
- Czy Java jest naprawdę wolna, a jeśli tak, to dlaczego?
- Dlaczego Java jest postrzegana jako wolna, mimo że jest szybsza niż wiele alternatyw?
Pierwsze z nich jest mniej więcej pytaniem „jak długa jest lina”. Wszystko sprowadza się do twojej definicji „wolnego”. W porównaniu do czystego interpretera, Java jest niezwykle szybka. W porównaniu do innych języków, które są (normalnie) kompilowane do jakiegoś kodu bajtowego, a następnie dynamicznie kompilowane do kodu maszynowego (np. C # lub cokolwiek innego w .NET) Java jest mniej więcej równa. W porównaniu z językami, które zwykle są kompilowane do czystego kodu maszynowego, i mają (często duże) zespoły ludzi pracujące nad niczym innym, jak tylko ulepszaniem swoich optymalizatorów (np. C, C ++, Fortran, Ada) Java radzi sobie w kilku sprawach, ale ogólnie bywa co najmniej nieco wolniejszy.
Wiele z tego dotyczy przede wszystkim implementacji - w zasadzie sprowadza się to do faktu, że użytkownik czeka na uruchomienie kompilatora dynamicznego / JIT, więc jeśli nie masz programu, który uruchamia się przez dłuższy czas, jest to trudno uzasadnić, że kompilator spędza dużo czasu na trudnych optymalizacjach. Dlatego większość kompilatorów Java (i C # itp.) Nie wkłada wiele wysiłku w naprawdę trudne optymalizacje. W wielu przypadkach mniej zależy od tego, jakie optymalizacje są wykonywane, niż od ich zastosowania. Wiele problemów związanych z optymalizacją zostało zakończonych NP, więc ich czas rośnie szybko wraz z wielkością atakowanego problemu. Jednym ze sposobów na utrzymanie czasu w granicach rozsądku jest zastosowanie optymalizacji do czegoś takiego jak pojedyncza funkcja na raz. Gdy tylko programista czeka na kompilator, możesz sobie pozwolić na dłuższe działanie i zastosować tę samą optymalizację do znacznie większych części programu. Podobnie, kod niektórych optymalizacji jest dość włochaty (i dlatego może być dość duży). Ponownie, ponieważ użytkownik czeka na załadowanie tego kodu (a czas uruchamiania JVM jest często znaczącym czynnikiem w całym czasie), implementacja musi zrównoważyć czas zaoszczędzony w jednym miejscu w porównaniu do utraconego w innym - i biorąc pod uwagę, jak mało kodu korzysta z owłosionych optymalizacji, utrzymywanie małej JVM jest zwykle bardziej korzystne.
Drugi problem polega na tym, że w Javie często pojawia się mniej więcej jedno rozwiązanie uniwersalne. Na przykład dla wielu programistów Java Swing jest zasadniczo jedyną dostępną biblioteką okienkową. W czymś takim jak C ++ istnieje dosłownie dziesiątki bibliotek okienkowych, struktur aplikacji itp., Każda z własnym zestawem kompromisów między łatwością użycia a szybkim wykonaniem, spójnym wyglądem i działaniem vs. rodzimym wyglądem i tak dalej. Jedynym faktem jest to, że niektóre (np. Qt) mogą być dość drogie (przynajmniej do użytku komercyjnego).
Po trzecie, dużo kodu napisanego w C ++ (a jeszcze bardziej C) jest po prostu starsze i bardziej dojrzałe. W większości zawiera rdzeń procedur napisanych kilkadziesiąt lat temu, gdy spędzanie dodatkowego czasu na optymalizacji kodu było normalnym, oczekiwanym zachowaniem. To często ma rzeczywistą zaletę w kodzie, który jest mniejszy i szybszy. C ++ (lub C) zasługuje na to, że kod jest mały i szybki, ale tak naprawdę jest to o wiele więcej produkt dewelopera i ograniczenia czasu pisania kodu. W pewnym stopniu prowadzi to do samospełniającej się przepowiedni - kiedy ludzie dbają o szybkość, często wybierają C ++, ponieważ ma tę reputację. Włożyli dodatkowy czas i wysiłek w optymalizację, a napisano nową generację szybkiego kodu C ++.
Podsumowując, normalna implementacja Java sprawia, że maksymalna optymalizacja jest co najmniej problematyczna. Co gorsza, gdy Java jest widoczna , takie rzeczy jak okienkowanie zestawów narzędzi i czas uruchamiania JVM często odgrywają większą rolę niż szybkość wykonywania samego języka. W wielu przypadkach C i C ++ również doceniają to, co tak naprawdę jest wynikiem cięższej pracy przy optymalizacji.
Co do drugiego pytania, myślę, że w dużej mierze jest to kwestia ludzkiej natury w pracy. Kilku fanatyków twierdzi, że Java jest niesamowicie szybka. Ktoś go wypróbuje i stwierdzi, że uruchomienie nawet trywialnego programu zajmuje kilka sekund, a po uruchomieniu jest powolny i niezdarny. Niewielu prawdopodobnie przeszkadza w analizowaniu rzeczy, aby zdać sobie sprawę, że znaczną część tego stanowi czas uruchomienia JVM, oraz fakt, że kiedy po raz pierwszy wypróbowują rzeczy, żaden kod nie został jeszcze skompilowany - część kodu jest interpretowana, a niektóre są kompilowane podczas oczekiwania. Co gorsza, nawet jeśli działa wystarczająco szybko, wygląd i styl zwykle wydają się obce i niezdarne dla większości użytkowników, więc nawet jeśli obiektywne pomiary wykazały szybki czas reakcji, nadal wydawałoby się niezdarny.
Dodanie ich do siebie prowadzi do dość prostej i naturalnej reakcji: że Java jest powolna, brzydka i niezdarna. Biorąc pod uwagę szum mówiący, że jest naprawdę szybki, istnieje tendencja do przesadnej reakcji i wniosku, że jest to strasznie powolne, zamiast (dokładniejszego) „nieco wolniejszego, i to głównie w określonych okolicznościach”. Jest to na ogół najgorsze dla programisty piszącego kilka pierwszych programów w tym języku. Wykonanie programu „witaj świecie” w większości języków jest natychmiastowe, ale w Javie jest zauważalna przerwa podczas uruchamiania JVM. Nawet czysty interpreter, który działa znacznie wolniej na ciasnych pętlach i taki nadal często pojawia się szybciej w przypadku takiego kodu, po prostu dlatego, że można go załadować i zacząć wykonywać nieco wcześniej.