W zasadzie, gdy bajt kod jest skompilowany i załadowany, to zawsze powinien być interpretowany co najmniej tak szybko jak oryginalny AST tłumacza. Jakiś kod będzie korzystał z dużych przyspieszeń, zwykle jest to kod z wieloma skalarnymi operacjami i pętlami, w których większość czasu spędza się na interpretacji R (widziałem przykłady z 10-krotnym przyspieszeniem, ale arbitralne mikro-testy mogły w istocie nadmuchać to w razie potrzeby). Niektóre kody będą działały z tą samą prędkością, zazwyczaj jest to kod wektoryzowany, przez co prawie nie ma czasu na interpretację. Teraz sama kompilacja może być wolna. W związku z tym kompilator just in time nie kompiluje teraz funkcji, gdy zgaduje, że nie będzie się opłacał (a zmiany heurystyczne zmieniają się w czasie, jest to już w 3.4.x). Heurystyki nie zawsze są trafne, więc mogą zdarzyć się sytuacje, w których kompilacja się nie opłaca. Typowymi problematycznymi wzorcami są generowanie kodu, modyfikacja kodu i manipulowanie powiązaniami środowisk przechwytywanych w zamknięciach.
Pakiety można skompilować w czasie instalacji, aby koszt kompilacji nie był płacony (wielokrotnie) w czasie wykonywania, przynajmniej dla kodu, który jest znany z wyprzedzeniem. Jest to teraz domyślna wersja rozwojowa R. Chociaż ładowanie skompilowanego kodu jest znacznie szybsze niż kompilowanie go, w niektórych sytuacjach może być ładowany nawet kod, który nie zostanie wykonany, więc faktycznie może to być narzut, ale ogólnie wstępna kompilacja jest korzystna. Ostatnio niektóre parametry GC zostały dostrojone w celu zmniejszenia kosztów ładowania kodu, który nie zostanie wykonany.
Moja rekomendacja dla twórców pakietów będzie polegać na używaniu domyślnych ustawień (kompilacja "just-in-time" jest teraz domyślnie włączona w wydanych wersjach, kompilacja bajtów w czasie instalacji pakietu jest już w wersji rozwojowej). Jeśli znajdziesz przykład, w którym kompilator kodu bajtowego nie działa dobrze, prześlij raport o błędzie (widziałem też przypadek z udziałem rpart
we wcześniejszych wersjach). Poleciłbym przeciw generowaniu kodu i manipulowaniu kodami, szczególnie w gorących pętlach. Obejmuje to definiowanie zamknięć, usuwanie i wstawianie powiązań w środowiskach przechwytywanych przez zamknięcia. Zdecydowanie nie powinno się robić eval(parse(text=
w gorących pętlach (a to już było złe bez kompilacji bajtów). Zawsze lepiej jest używać gałęzi niż dynamicznie generować nowe zamknięcia (bez gałęzi). Lepiej jest pisać kod z pętlami niż dynamicznie generować kod z dużymi wyrażeniami (bez pętli). Teraz z kompilatorem kodu bajtowego, obecnie dobrze jest napisać pętle działające na skalarach w R (wydajność nie będzie tak zła jak wcześniej, więc można częściej uciec bez przełączania na C dla części krytycznych pod względem wydajności) .
Nie jestem pewien trafień wydajności (inne niż początkowe kompilacjach (a może zwiększone zużycie pamięci)), ale „Uwaga: brak widocznych wiążące” wiadomości często może być przytłaczająca do początkujących (np w przypadku korzystania ggplot2) i może wyrzuć tab-complete (przynajmniej są dla mnie) – mweylandt
Witaj mweylandt. Czy zdajesz sobie sprawę, co oznacza ten masaż błędu? –
Umieszczam 'ByteCompile: true' w pliku DESCRIPTION moich pakietów, ponieważ tworzę nowe wersje i wygląda na to, że działa poprawnie. Zrobiłem jeden mały test 'http: // www.johnmyleswhite.com/notebook/2012/03/31/julia-i-love-you/comment-page-1/# comment-19522' i skompilowaną wersję bajtową,' fib2c' działał 4x szybciej niż zwykły, 'fib2a'. W niektórych przypadkach R jest już szybki, nawet bez kompilacji bajtów (na przykład wysoce wektoryzowany kod wykorzystujący C pod spodem), aw tych przypadkach jest oczywiście mała szansa na przyspieszenie - jest to głównie przydatne dla powolnego kodu R. –