Istnieje wiele powodów, dla których można rozważyć wybór języka X zamiast języka Y. Czytelność programu, łatwość programowania, przenośność na wiele platform, istnienie dobrych środowisk programowania może być takimi przyczynami. Zastanowię się jednak tylko nad szybkością wykonania, zgodnie z żądaniem zawartym w pytaniu. Pytanie wydaje się nie uwzględniać na przykład tempa rozwoju.
Dwa języki mogą się kompilować do tego samego kodu bajtowego, ale nie oznacza to, że zostanie wygenerowany ten sam kod,
W rzeczywistości bytecode jest kodem tylko dla konkretnej maszyny wirtualnej. Ma zalety inżynieryjne, ale nie wprowadza zasadniczych różnic w bezpośredniej kompilacji dla określonego harware. Równie dobrze możesz rozważyć porównanie dwóch języków skompilowanych do bezpośredniego wykonania na tym samym komputerze.
To powiedziawszy, kwestia względnej szybkości języków jest stara i sięga pierwszych kompilatorów.
Przez wiele lat w tamtych czasach profesjonalista uważał, że odręczny kod jest szybszy niż kod skompilowany. Innymi słowy, język maszynowy był uważany za szybszy niż języki wysokiego poziomu, takie jak Cobol lub Fortran. I było zarówno szybsze, jak i zwykle mniejsze. Języki wysokiego poziomu wciąż się rozwijały, ponieważ były znacznie łatwiejsze w użyciu dla wielu osób, które nie były informatykami. Koszt użycia języków wysokiego poziomu miał nawet nazwę: współczynnik rozszerzenia, który może dotyczyć wielkości generowanego kodu (bardzo ważna kwestia w tamtych czasach) lub liczby faktycznie wykonanych instrukcji. Pomysł był głównie eksperymentalny, ale początkowo stosunek był większy niż 1, ponieważ kompilatory wykonały dość prostą robotę według dzisiejszych standardów.
W ten sposób język maszynowy był szybszy niż powiedzieć Fortran.
Oczywiście zmieniło się to z biegiem lat, gdy kompilatory stały się bardziej wyrafinowane, do tego stopnia, że programowanie w asemblerze jest teraz bardzo rzadkie. W przypadku większości aplikacji programy w asemblerze słabo konkurują z kodem generowanym przez optymalizację kompilatorów.
To pokazuje, że jednym z głównych problemów jest jakość kompilatorów dostępnych dla rozważanego języka, ich zdolność do analizy kodu źródłowego i odpowiedniej jego optymalizacji.
Ta zdolność może zależeć w pewnym stopniu od cech języka, aby podkreślić strukturalne i matematyczne właściwości źródła, aby ułatwić pracę kompilatorowi. Na przykład język może pozwalać na dołączanie instrukcji o właściwościach algebraicznych funkcji zdefiniowanych przez użytkownika, aby umożliwić kompilatorowi wykorzystanie tych właściwości do celów optymalizacji.
Proces kompilacji może być łatwiejszy, dzięki czemu powstaje lepszy kod, gdy paradygmat programowania języka jest bliższy funkcjom maszyn, które zinterpretują kod, zarówno rzeczywistej, jak i wirtualnej.
Inną kwestią jest to, czy paradygmaty zaimplementowane w języku są zamknięte dla rodzaju programowanego problemu. Należy się spodziewać, że język programowania wyspecjalizowany w określonych paradygmatach programowania będzie bardzo skutecznie kompilował funkcje związane z tym paradygmatem. Dlatego wybór języka programowania może zależeć, dla jasności i szybkości, od wyboru języka programowania dostosowanego do rodzaju programowanego problemu.
Popularność C w programowaniu systemu wynika prawdopodobnie z faktu, że C jest zbliżony do architektury maszyny, a programowanie systemu jest również bezpośrednio związane z tą architekturą.
Niektóre inne problemy będą łatwiejsze do zaprogramowania, dzięki szybszemu wykonaniu przy użyciu programowania logiki i języków rozwiązywania ograniczeń .
Złożone systemy reaktywne mogą być bardzo skutecznie programowane za pomocą specjalistycznych synchronicznych języków programowania, takich jak Esterel, który zawiera bardzo specjalistyczną wiedzę na temat takich systemów i generuje bardzo szybki kod.
Lub, na przykład, niektóre języki są wysoce wyspecjalizowane, takie jak języki opisu składni używane do programowania parserów. Parser generator to nic innego jak kompilator dla tych języków. Oczywiście nie jest to kompletna metoda Turinga, ale te kompilatory są wyjątkowo dobre ze względu na swoją specjalizację: tworzenie wydajnych programów parsujących. Ponieważ dziedzina wiedzy jest ograniczona, techniki optymalizacji mogą być bardzo wyspecjalizowane i bardzo dokładnie dostrojone. Te generatory parsera są zwykle znacznie lepsze niż to, co można uzyskać, pisząc kod w innym języku. Istnieje wiele wysoce wyspecjalizowanych języków z kompilatorami, które wytwarzają doskonały i szybki kod dla ograniczonej klasy problemów.
Dlatego przy pisaniu dużego systemu może być wskazane, aby nie polegać na jednym języku, ale wybrać najlepszy język dla różnych składników systemu. To oczywiście rodzi problemy z kompatybilnością.
Inną kwestią, która często ma znaczenie, jest po prostu istnienie wydajnych bibliotek dla programowanych tematów.
Wreszcie, szybkość nie jest jedynym kryterium i może być w konflikcie z innymi kryteriami, takimi jak bezpieczeństwo kodu (na przykład w odniesieniu do złych danych wejściowych lub odporność na błędy systemowe), użycie pamięci, łatwość programowania (chociaż zgodność paradygmatu może w rzeczywistości pomóc ), rozmiar kodu obiektu, łatwość konserwacji programu itp.
Prędkość nie zawsze jest najważniejszym parametrem. Może również przybierać różne formy, na przykład złożoność, która może być średnią złożonością lub gorszą złożonością przypadku. Ponadto w dużym systemie, podobnie jak w mniejszym programie, są części, w których prędkość ma kluczowe znaczenie, i inne, w których nie ma to większego znaczenia. I nie zawsze łatwo jest to ustalić z góry.