Pytanie Jakie są zalety kodu bajtowego w stosunku do natywnego kodu? [Zamknięte]


Wygląda na to, że wszystko, co możesz zrobić z kodem bajtowym, możesz zrobić równie łatwo i znacznie szybciej w natywnym kodzie. Teoretycznie można nawet zachować niezależność od platformy i języka, rozpowszechniając programy i biblioteki w bajtodzie, a następnie kompilując je do natywnego kodu podczas instalacji, zamiast go JITing.

Więc na ogół, kiedy chcesz wykonać kod bajtowy zamiast natywnego?


38
2017-09-07 04:36


pochodzenie




Odpowiedzi:


Hank Shiffman z SGI powiedział (dawno temu, ale to prawda):

Istnieją trzy zalety Javy   używanie kodu bajtowego zamiast przechodzenia do niego   macierzysty kod systemu:

  1. Ruchliwość: Każdy rodzaj komputera ma swoje unikalne instrukcje   zestaw. Podczas gdy niektóre procesory obejmują   instrukcje dla ich poprzedników,   to ogólnie prawda, że ​​program   który działa na jednym rodzaju komputera   nie będzie działał na żadnym innym. Dodaj w   usługi świadczone przez działające   system, który każdy system opisuje w   swój unikalny sposób, a ty masz   problem ze zgodnością. W ogóle ty   nie można napisać i skompilować programu dla   jeden rodzaj systemu i uruchom go na dowolnym   inne bez dużego nakładu pracy. Java dostaje   wokół tego ograniczenia przez wstawienie   jego maszyna wirtualna między   zastosowanie i rzeczywiste środowisko   (komputer + system operacyjny). Jeżeli   aplikacja jest kompilowana do bajtu Java   kod i ten kod bajtu jest interpretowany   w ten sam sposób w każdym środowisku   możesz napisać pojedynczy program, który   będzie działać na wszystkich różnych   platformy, na których obsługiwana jest Java.   (Taka jest teoria   praktyka jest zawsze mała   niezgodności, na które trzeba czekać   programista.)

  2. Bezpieczeństwo: Jedną z zalet Javy jest jej integracja z siecią. Obciążenie   strona internetowa, która używa Javy do twojej   przeglądarka i kod Java to   automatycznie pobierane i wykonywane.   Ale co jeśli kod zniszczy pliki,   czy przez złośliwość czy niechlujstwo   ze strony programisty? Jawa   uniemożliwia wykonywanie pobranych apletów   cokolwiek niszczycielskiego przez niedozwolone   potencjalnie niebezpieczne operacje.   Zanim zezwoli na uruchomienie kodu   analizuje go pod kątem prób ominięcia   bezpieczeństwo. Weryfikuje, czy dane są   używane konsekwentnie: kod, który   manipuluje elementem danych jako liczbą całkowitą   na pewnym etapie, a następnie próbuje go użyć   jako wskaźnik później zostanie złapany i   uniemożliwione wykonanie. (Java   język nie pozwala na wskaźnik   arytmetyczna, więc nie możesz pisać w Javie   kod do zrobienia tego, co właśnie opisaliśmy.   Jednak nic nie można zapobiec   ktoś od pisania niszczącego bajtu   kodują się przy użyciu szesnastkowego   edytor, a nawet budowanie bajtu Java   kod asembler.) Zasadniczo nie jest   możliwa analiza programu   kod maszynowy przed wykonaniem i   określić, czy coś robi   zły. Sztuczki takie jak pisanie   samodyfikujący się kod oznacza zło   operacje mogą nawet nie istnieć do   później. Ale zaprojektowano kod bajtowy Java   dla tego rodzaju zatwierdzenia: to   nie ma instrukcji a   złośliwy programista ukryłby się   ich napaść.

  3. Rozmiar: W świecie mikroprocesorów RISC jest na ogół lepszy   nad CISC. Lepiej mieć małą   zestaw instrukcji i korzystać z wielu szybko   instrukcje wykonywania pracy, niż mieć   wiele złożonych operacji wdrożonych jako   pojedyncze instrukcje. Projekty RISC   wymagają mniejszej liczby bramek na chipie   realizować swoje instrukcje, pozwalając   więcej miejsca na rurociągi i inne   techniki wykonywania każdej instrukcji   szybciej. W tłumaczeniu   nic z tego nie ma znaczenia. Jeśli chcesz   wdrożyć jedną instrukcję dla   zmień instrukcję ze zmienną   długość w zależności od liczby przypadków   klauzule, nie ma powodu, aby nie robić   więc. W rzeczywistości złożony zestaw instrukcji   jest zaletą dla sieci   język: oznacza to samo   program będzie mniejszy (mniej   instrukcje o większej złożoności),   co oznacza mniej czasu na przeniesienie   w naszej ograniczonej prędkości sieci.

Więc rozważając kod bajtowy w stosunku do natywnego, zastanów się, które kompromisy między przenośnością, bezpieczeństwem, rozmiarem i szybkością wykonania chcesz osiągnąć. Jeśli prędkość jest jedynym ważnym czynnikiem, należy natywnie. Jeśli którykolwiek z pozostałych jest ważniejszy, należy przejść do kodu bajtowego.

Dodam też, że utrzymywanie serii kompilacji opartych na systemach operacyjnych i architekturze o tej samej podstawie kodowej dla każdego wydania może stać się bardzo uciążliwe. Ogromną wygraną jest używanie tego samego kodu bajtowego Java na wielu platformach i "po prostu działać".


31
2017-09-07 04:46



4 lata później ... Przenośność: kompilatory, które produkują natywny kod, mogą się krzyżować, podobnie jak gc (The official Udać się kompilator), co czyni go tak prostym. Bezpieczeństwo: Klient natywny uruchamia natywny kod w piaskownicy, ograniczając tym samym uprawnienia. Rozmiar: rzadko jest to problem w dzisiejszych czasach, nawet na urządzenia mobilne. - Moshe Revah
@Zippoxer Co to za cztery lata? Kompilacja krzyżowa to bardzo stara koncepcja. Ale nadal musisz skompilować kod dla każdej platformy osobno. Wirtualizacja nie jest również nową koncepcją, ale wirtualizacja kodu napisanego dla natywnego wykonywania nie jest tym samym, co wirtualizacja kodu, który został specjalnie zaprojektowany do pracy w piaskownicy. Jeśli chodzi o rozmiar, w rzeczywistości nie nazwałbym kodu BIS w języku Java. To samo dotyczy CIL. - Malcolm


Wydajność zasadniczo dowolnego programu ulegnie poprawie, jeśli zostanie skompilowana, wykonana z profilowaniem, a wyniki zostaną zwrócone do kompilatora w drugim przebiegu. Ścieżki kodu, które są faktycznie używane, będą bardziej agresywnie zoptymalizowane, pętle zostaną rozwinięte do dokładnie odpowiedniego poziomu, a ścieżki instrukcji będą ustawione tak, aby zmaksymalizować I $ trafień.

Wszystkie dobre rzeczy, ale prawie nigdy się to nie kończy, ponieważ irytujące jest przechodzenie przez tak wiele kroków, aby zbudować plik binarny.

Jest to zaleta polegająca na uruchomieniu kodu bajtowego przez pewien czas przed skompilowaniem go do kodu natywnego: informacje profilowania są automatycznie dostępne. Wynik po kompilacji Just-In-Time to wysoce zoptymalizowany kod natywny dla konkretnych danych przetwarzanych przez program.

Możliwość uruchomienia kodu bajtowego umożliwia również bardziej agresywną optymalizację natywną, niż można by bezpiecznie użyć statycznego kompilatora. Na przykład, jeśli jeden z argumentów funkcji zostanie oznaczony jako zawsze NULL, cała obsługa tego argumentu może być po prostu pominięta z natywnego kodu. Nastąpi krótkie sprawdzenie poprawności argumentów w prologu funkcji, jeśli ten argument nie jest NULL, maszyna wirtualna przerywa powrót do kodu bajtowego i rozpoczyna profilowanie ponownie.


15
2017-09-07 04:56





Bajtek tworzy dodatkowy poziom pośredni.

Zalety tego dodatkowego poziomu pośredniego to:

  • Niezależność od platformy
  • Potrafi utworzyć dowolną liczbę języków programowania (składnię) i zmusić je do kompilacji do tego samego kodu bajtowego.
  • Można łatwo tworzyć konwertery z różnymi językami
  • x86, x64 i IA64 nie muszą być kompilowane jako oddzielne pliki binarne. Musi być zainstalowana tylko właściwa maszyna wirtualna.
  • Każdy system operacyjny musi po prostu utworzyć maszynę wirtualną i będzie obsługiwał ten sam program.
  • Kompilacja na czas pozwala aktualizować program, zastępując pojedynczy poprawiony plik źródłowy. (Bardzo korzystne dla stron internetowych)

Niektóre wady:

  • Wydajność
  • Łatwiej dekompilować

9
2017-09-07 04:44





Wszystkie dobre odpowiedzi, ale mój gorący przycisk został trafiony - wydajność.

Jeśli uruchamiany kod poświęca cały swój czas na wywoływanie procedur bibliotecznych / systemowych - operacji na plikach, operacji na bazach danych, wysyłania wiadomości w oknach, to nie ma to większego znaczenia, jeśli jest to JITted, ponieważ większość czasu jest poświęcana na oczekiwanie na te niższe poziomy. operacje na poziomie do ukończenia.

Jednak, gdyby kod zawiera rzeczy, które zwykle nazywamy "algorytmami", które muszą być szybkie i nie wymagają wiele czasu na wywoływanie funkcji, i jeśli są one używane wystarczająco często, aby stanowić problem z wydajnością, to JIT jest bardzo ważny.


3
2018-01-06 21:22





Myślę, że właśnie odpowiedziałeś na własne pytanie: niezależność od platformy. Niezależny od platformy kod bajtowy jest produkowany i dystrybuowany do platformy docelowej. Po uruchomieniu jest szybko kompilowany do natywnego kodu przed rozpoczęciem wykonywania lub jednocześnie (Just In Time). Java JVM i prawdopodobnie środowiska wykonawcze .NET działają na tej zasadzie.


2
2017-09-07 04:38





Tutaj: http://slashdot.org/developers/02/01/31/013247.shtml

Zobacz, co mają do powiedzenia o tym geekowie Slashdot! Trochę przestarzałe, ale bardzo dobre komentarze!


2
2017-09-07 04:56





Idealnie byłoby mieć przenośny kod bajtowy, który kompiluje Just In Time do natywnego kodu. Sądzę, że interpretatory kodu bajtowego, które istnieją bez JIT, wynikają przede wszystkim z praktycznego faktu, że kompilacja kodu natywnego zwiększa złożoność maszyny wirtualnej. Budowanie, debugowanie i utrzymywanie tego dodatkowego komponentu zajmuje dużo czasu. Nie wszyscy mają czas lub zasoby, aby podjąć to zobowiązanie.

Drugim czynnikiem jest bezpieczeństwo. Znacznie łatwiej jest zweryfikować, czy tłumacz nie ulegnie awarii, niż zagwarantować to samo dla natywnego kodu.

Trzeci to wydajność. Często może zająć więcej czasu na wygenerowanie kodu maszynowego niż na interpretowanie kodu bajtowego dla małych fragmentów kodu uruchamianych tylko raz.


1
2017-09-07 04:50





Przenośność i niezależność platformy to prawdopodobnie najbardziej znaczące zalety kodu bajtowego w porównaniu z natywnym kodem.


0
2018-04-24 19:32