W jaki sposób sprawdzany jest typ dynamicznego interpretera / kompilatora języka, takiego jak JavaScript?

11

W językach dynamicznych, takich jak JavaScript lub Python, typ zmiennej jest określany w czasie wykonywania. Jest to jeden z powodów, dla których są one wolniejsze niż języki pisane, takie jak Java.

Jak przeprowadzana jest kontrola typu? Co jest zasadniczym powodem, dla którego ten proces jest powolny?


źródło
Nie są wolniejsze, ponieważ są dynamiczne, są wolniejsze, ponieważ trudniej jest je przyspieszyć. JavaScript jest właściwie najbardziej zoptymalizowany i jest dość szybki.
Derek Litz,

Odpowiedzi:

5

Pytanie jest zamieszane.

Zakłada się, że sprawdzanie typu jest powolne, co niekoniecznie ma miejsce.

Pytanie wydaje się również mylić proces wysyłki typu ze sprawdzaniem typu i są to dwie różne rzeczy. Jeden to proces wykonywany w czasie wykonywania, drugi proces w czasie kompilacji. Podejrzewam, że tak naprawdę pytanie dotyczy wysyłki typu.

Wysyłanie typów może wprowadzać narzut w czasie wykonywania, ponieważ obliczenia spędzają czas na instrukcjach, które dynamicznie decydują o tym, jakie działanie należy podjąć, na podstawie typów wartości, które widzi w czasie wykonywania. np. w dynamicznym języku, jeśli zastosuję „+” do dwóch rzeczy, może to oznaczać dodawanie liczbowe lub łączenie ciągów, więc muszę poświęcić czas na sprawdzenie, co jest pod ręką, aby zdecydować, co robić. Istnieją strategie oceny, które mogą obniżyć koszty dynamicznej wysyłki. (np. śledzenie JIT)

Odnośnie do sprawdzania typu w JavaScript, patrz: http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/ . Aby uzyskać bardziej ogólny przegląd działania sprawdzania typów, algorytm opisuje standardowy podręcznik języka programowania. Na przykład http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

dyoo
źródło
Napisałem również małą ankietę na temat śledzenia JIT i języków dynamicznych w hashcollision.org/comprehensive/tracing.pdf
Tłumacz języka JavaScript przenosi bity znacznika z każdą wartością do wysyłki typu. Czy mógłbyś trochę rozwinąć tę kwestię? Na przykład, do czego służą bity znaczników? Czy trochę odpowiada typowi?
Pojęcie typu nie zawsze jest powiązane z reprezentacją. Na przykład możemy mieć pojęcie typu „mila” a „kilometrowe” i rozsądne jest posiadanie języka, który w czasie kompilacji może wykrywać statycznie, czy obliczenia niewłaściwie stosują operacje na wartościach, które psują typy . Można sobie wyobrazić, że będą miały taką samą reprezentację, a jeśli kompilator może w czasie kompilacji zagwarantować, że nigdy nie będą mieszane, nie ma powodu, dla którego wartości wymagałyby dodatkowego oznaczenia w reprezentacji.
1
Kontynuacja: ale często, szczególnie w dynamicznych językach, chcesz reprezentować wartości różnych typów. Istnieje kilka sposobów na dyskryminację. Znaczniki typów są powszechne, ale istnieją inne techniki. Na przykład możesz umieścić niektóre typy w zablokowanych obszarach pamięci. Zobacz „Reprezentowanie informacji o typie w językach dynamicznie wpisywanych”. lambda-the-ultimate.org/node/3912 do kompleksowego przeglądu technik reprezentacji.
7

Mówiąc najprościej, w nietypowych językach każdy punkt odniesienia do obiektu zawierającego zarówno typ, jak i wartość. Na przykład var a = 3wskazuje na instancję, która zawiera wartość 3 i typ int, jeśli to zrobisz a = "bla", odwołanie zostanie zaktualizowane do instancji zawierającej ciąg „bla” i ciąg typu, stary obiekt zostanie odrzucony itp.

Jest to powolne, ponieważ za każdym razem, gdy a + bnależy wykonać operację (np. ) Na tym podstawowym typie, środowisko wykonawcze musi najpierw wyrejestrować obiekty, sprawdzić, czy ich typ jest kompatybilny, wykonać operację, utworzyć nowy obiekt.

Natomiast a + bw C ++ lub Java sprawdza w czasie kompilacji , czy typy są poprawne i kompatybilne, a następnie a i b są przechowywane jako wartości bezpośrednie (nie odniesienia), a dodanie jest prostą operacją procesora na tych wartościach.

Oczywiście wszystko to jest bardzo teoretyczne. W praktyce można wykonać wiele optymalizacji tego procesu, aby uniknąć większości kosztów ogólnych, a dynamicznie pisane języki mogą być dość szybkie.

solendil
źródło
1
Sztuczki takie jak polimorficzne wbudowane pamięci podręczne mogą znacznie poprawić wydajność. Pisma Davida Ungara (Jaźń) i Eliota Mirandy (Squeak, maszyny wirtualne Visual Works Smalltalk) są najbardziej pouczające, jeśli chodzi o dynamiczne działanie języka.
Frank Shearar,
0

Każda wartość jest przechowywana razem z jej rodzajem, który należy najpierw sprawdzić. Także konwersje mówią, że z ciągu na ciąg przechodzi przez kontrolę w locie.

Joop Eggen
źródło
Tak, to jest to, to tylko kontrola czasu wykonywania, nic szczególnego.
anon