Euphoria Wskazówki dotyczące wydajności

Original: http://rapideuphoria.com/perform.htm

Porady ogólne

Jeśli Twój program jest na tyle szybki, zapomnieć o przyspieszając go. Po prostu zrób to prosty i czytelny.

Jeśli Twój program jest zbyt powolny, końcówki poniżej prawdopodobnie nie rozwiąże problemu. Powinieneś znaleźć lepszy ogólny algorytm.

Najprostszym sposobem, aby zdobyć trochę prędkości jest wyłączenie w czasie wykonywania kontroli typu. Wstaw linię:

bez type_check

w górnej części głównego pliku Ex, przed każda zawierać oświadczenia. Będziesz zwykle uzyskać od 0 do 20 procent w zależności od rodzaju zostały zdefiniowane i plików, które są w tym. Większość standardowych bibliotek zrobić kilka zdefiniowanych przez użytkownika typu kontroli.Program, który jest całkowicie bez zdefiniowanego przez użytkownika typu kontroli może być jeszcze przyspieszyła nieznacznie.

Należy także pamiętać, aby usunąć, lub komentarz out, każdy

z cienia

profil

z profile_time

oświadczenia. z cienia (nawet bez zawijania do śledzenia ()), a także z profilu można łatwo wolno ci o 10% lub więcej. z profile_time może spowolnić o 1%. Każda z tych opcji będzie zużywać więcej pamięci, jak również.

Obliczanie przy użyciu wartości całkowite są szybsze niż obliczeń przy użyciu liczb zmiennoprzecinkowych

Deklarować zmienne jako liczba całkowita, a nie atomu w miarę możliwości, jak i sekwencji, a nie obiektu, gdzie to możliwe. To zazwyczaj zyskuje Ci kilka procent prędkości.

W wypowiedzi z udziałem obliczeń zmiennoprzecinkowych to zwykle szybciej pisać stałych liczb w postaci pływających, na przykład punkt gdy x ma wartość zmiennoprzecinkową, powiedzmy, x = 9,9

zmienić:

= x * 5

do:

x = x * 5,0

Oszczędza to interpreter z konieczności konwertowania całkowitą 5 do zmiennoprzecinkowych 5,0 za każdym razem.

Euforia robi ocenę zwarcie jeśli elsif, a gdy warunki zaangażowania i i lub. Euforia zatrzyma oceny wszelkie warunki po to określa, czy warunek jest prawdziwy czy nie. Na przykład w if-oświadczenie:

jeśli x> 20 i y = 0 Then

end if

Test „, y = 0“ zostanie wykonana tylko wtedy, gdy „x> 20“ jest prawdziwe.

Dla maksymalnej prędkości, możesz zamówić swoje testy. Czy „x> 20“ pierwsze, jeśli jest bardziej prawdopodobne, że są fałszywe, niż „y = 0“.

W ogóle, z stan „A i B“, Euforia nie ocenia wyrażenie B, jeśli jest fałszywe (zero). Podobnie, w stanie takim jak „A, B“, B nie będą oceniane przy jest prawdą (non-zero).

Proste, czy-wypowiedzi są wysoce zoptymalizowany. Z obecnej wersji interpretera, zagnieżdżone proste, jeśli na które porównują liczby całkowite są zwykle nieco szybciej niż pojedyncze zwarcia if-rachunku, np:

jeśli x> 20 następnie

Jeśli y = 0, a następnie

end if

end if

Szybkość dostępu do zmiennych prywatnych, zmiennych lokalnych i globalnych zmiennych jest taka sama.

Nie ma spadku wydajności do definiowania stałych w porównaniu podłączenie twardych oznaczonych numerami dosłowne.Prędkość:

y = x * MAX

dokładnie takie same, jak:

y = x * 1.000

gdzie już wcześniej zdefiniowane:

stała MAX = 1000

Nie ma kary za to, że wydajność dużo komentarzy w programie. Komentarze są całkowicie ignorowane. Nie są one wykonane w dowolny sposób. To może potrwać kilka milisekund dłużej obciążenia wstępnego w programie, ale to jest bardzo mała cena za przyszłej konserwacji, a gdy wiążą się z programu, lub tłumaczyć program na C, wszystkie komentarze są usuwane na zewnątrz, więc koszt staje się zera bezwzględnego.

Wyniki pomiaru

W dowolnym języku programowania, a zwłaszcza w Euphoria, naprawdę trzeba dokonać pomiarów przed wyciągnięciem wniosków o wydajności.

Euforia zapewnia zarówno profilowanie wykonanie zliczania, a także profilowanie czasu (tylko DOS32). Zobacz refman.doc. Bardzo często możesz być zaskoczony wynikami tych profili. Skoncentrować swoje wysiłki na miejscach w programie, które korzystają wysoki procent całkowitego czasu (lub przynajmniej są wykonywane wiele razy.) Nie ma sensu, aby przepisywanie sekcji kodu, który używa 0,01% całkowitego czasu. Zazwyczaj będzie jedno miejsce, czy tylko kilka miejsc, gdzie kod szczypanie będzie istotną różnicę.

Możesz również mierzyć prędkość kodu za pomocą funkcji czasu (). na przykład

atom t

t = czas ()

dla i = 1 do 10000 robić

– Mały kawałek kodu tutaj

kończy się dla

? time () – t

Można przepisać mały kawałek kodu w różnych sposobów, aby zobaczyć w jaki sposób jest szybszy.

Jak przyspieszyć Loops

Profilowanie pokaże gorących punktów w programie. Są to zazwyczaj pętle wewnątrz. Spójrz na każdym obliczeniu wewnątrz pętli i zadać sobie pytanie, czy to naprawdę musi się zdarzyć przy każdym przejściu pętli, lub można to zrobić tylko raz, przed pętlą.

Konwersja mnoży się dodaje w pętli

Dodatek jest większa niż mnożenia. Czasami można wymienić mnożenie przez zmienną pętli, z dodatkiem. Coś jak:

dla i = 0 do 199 zrobić

Kapsa (screen_memory + i * 320, 0)

kończy się dla

staje się:

x = screen_memory

dla i = 0 do 199 zrobić

Kapsa (x, 0)

x = x + 320

kończy się dla

Zapisywanie wyników w zmiennych

Jest szybszy, aby zapisać wynik obliczeń w zmiennej, niż jest to przeliczyć później. Nawet coś tak prostego jak operacji indeksu dolnego lub dodanie 1 do zmiennej jest warta ocalenia.

Gdy masz sekwencję z wieloma poziomami indeksowanie, jest szybszy, aby zmienić kod tak:

dla i = 1 do 1000 nie

y [] [i] = y [] [i] +1

kończy się dla

do:

ya = y []

dla i = 1 do 1000 nie

ya [i] = ya [i] + 1

kończy się dla

y [] = ya

Więc robisz dwie operacje indeksy dolne na iteracji pętli, a nie 4. Operacje, ya = y [], y [] = ya są bardzo tanie. Oni po prostu skopiować wskaźnik. Oni nie skopiować całą sekwencję.

Istnieje niewielkie koszty podczas tworzenia nowej sekwencji przy użyciu {a, b, c}. Jeśli to możliwe, należy tę operację z krytycznym pętli poprzez przechowywanie go w zmiennej przed pętlą, a odwołanie do zmiennej wewnątrz pętli.

W-wyściółki rutynowa połączeń

Jeśli masz rutynę, która jest dość mały i szybki, ale nazywa się ogromną liczbę razy, zaoszczędzisz czas wykonując operację w jednej linii, a nie wywołanie procedury. Twój kod może stać się mniej czytelny, więc może lepiej byłoby w-line tylko w miejscach, które generują dużo połączeń do rutyny.

Operacje na sekwencjach

Euforia pozwala pracować na dużej sekwencji danych za pomocą pojedynczej instrukcji. To pozwala uniknąć pisania pętlę, gdzie przetwarza jeden element w swoim czasie. na przykład

x = {1,3,5,7,9}

y = {2,4,6,8,10}

z = x + y

w porównaniu z:

z = powtórz (0, 5) – w razie potrzeby

dla i = 1 do 5 to

z [i] = x [i] + y [i]

Kończy się dla

W większości języków tłumaczeń, jest o wiele szybciej przetwarzać całej sekwencji (tablica) w jednym sprawozdaniu, niż jest do wykonywania operacji skalarnych w pętli. To dlatego, że tłumacz ma dużą wartość obciążenia dla każdego rachunku to wykonuje. Euforia jest inna. Euforia jest bardzo szczupła, z niewielkim narzutem interpretacyjny, więc operacje na sekwencji nie zawsze wygrywają.Jedynym rozwiązaniem jest do czasu to w obie strony.Koszt-elementu jest zazwyczaj niższe podczas przetwarzania sekwencji w jednej instrukcji, ale są koszty ogólne związane z alokacją i dealokacji sekwencji, które mogą szalę w drugą stronę.

Niektóre specjalne Case optymalizacje

Euforia automatycznie optymalizuje niektórych szczególnych przypadków. x i y poniżej może być zmienne lub dowolnymi wyrażeniami.

x + 1 – szybciej niż ogólne x + y

1 + x – szybciej niż ogólny y + x

x * 2 – szybciej niż ogólna x * y

2 * x – szybciej niż ogólna y * x

x / 2 – szybciej niż ogólna x / y

floor (x / y), – w którym x i y są liczbami całkowitymi, jest większa niż x / y

floor (x / 2) – szybciej niż piętrze (x / y)

x poniżej jest prosta zmienna y jest dowolna zmienna lub wyrażenie:

x = append (x, y) – szybciej niż ogólna z = append (x, y)

x = poprzedzić (x, y) – szybciej niż ogólna z = poprzedzić (x, y)

x = x i y – gdy x jest znacznie większa od y,

– Jest szybciej niż ogólna z = x i y

Podczas pisania pętlę, która „rośnie“ sekwencję, przez dodanie lub łączenie danych na nim, razem, w ogóle, rośnie proporcjonalnie do kwadratu liczby (N) elementów, które są dodawane. Jednak, jeśli można użyć jednego ze specjalnych zoptymalizowanych form append (), PREPEND () lub konkatenacji wymienione powyżej, czas będzie rosła proporcjonalnie do odległości N (w przybliżeniu). To może zaoszczędzić mnóstwo czasu podczas tworzenia bardzo długą sekwencję. (Możesz również skorzystać z powtórki (), aby ustalić maksymalny rozmiar sekwencji, a następnie wypełnić elementów w pętli, jak opisano poniżej.)

Cesja z Wykonawcami

Dla większej prędkości, konwersji:

lewej stronie = lewej stronie op wyraz

do:

lewej stronie op = wyrażenie

gdy lewej stronie zawiera co najmniej 2 indeksami lub co najmniej jeden indeks i cięcia. We wszystkich przypadkach obydwa prostszych form pracować z tą samą prędkością (lub bardzo blisko same).

Porady grafiki pikseli

Tryb 19 to najszybszy tryb dla animacji i gier.

Pamięci wideo (w trybie 19) nie jest buforowane przez CPU. Zazwyczaj trwa to dłużej do odczytu lub zapisu danych na ekranie, niż do ogólnego obszaru pamięci, który można przeznaczyć. Zwiększa to wydajność wirtualnych ekranów, gdzie robisz wszystko twój aktualizacji obrazu w bloku pamięci, które można uzyskać z przydzielić (), a następnie okresowo mem_copy () uzyskany obraz do pamięci rzeczywistego ekranu. W ten sposób nie musisz czytać (powolny) pamięć ekranu.

Podczas drukowania pikseli, może się okazać, że tryby 257 i wyżej są szybkie w górnej części ekranu, ale powoli w pobliżu dna.

Porady w trybie tekstowym

Pisanie tekstu na ekranie za pomocą puts () i printf () jest raczej powolny. Jeśli to konieczne, w DOS32, można to zrobić o wiele szybciej, grzebie w pamięci wideo lub za pomocą display_text_image (). Istnieje bardzo duży narzut na każdym puts () na ekranie, a stosunkowo niewielki dodatkowy koszt na znak.Napowietrznych z EXW (Win32) jest szczególnie wysoki (na systemach Windows 95/98 / ME przynajmniej). Linux i FreeBSD są gdzieś pomiędzy DOS32 i WIN32 prędkości wyjściowej tekstu. Uzasadnione jest zatem, aby zbudować długi ciąg przed wywołaniem puts (), a nie wywołanie go dla każdego znaku. Nie ma przewagę do budowania ciąg dłużej niż jedną linię jednak.

Powolność wydajności tekstu wynika głównie obciążenie systemu operacyjnego.

Procedury Biblioteka

Niektóre wspólne procedury są bardzo szybko. Prawdopodobnie nie mógł wykonać zadanie szybciej w inny sposób, nawet jeśli używane C lub asemblera. Niektóre z nich to:

mem_copy ()
mem_set ()
powtórz ()

Inne procedury są dość szybko, ale może być w stanie wykonać zadanie szybciej, w niektórych przypadkach, jeśli szybkość była kluczowa.

x = powtórz (0100)

dla i = 1 do 100 nie

x [i] = i

kończy się dla

jest nieco szybciej niż:

x = {}

dla i = 1 do 100 nie

x = append (x, i)

Kończy się dla

bo append () musi przydzielić i zagospodarować przestrzeń jako x rośnie w wielkości. Przy powtórzeniu (), miejsca dla x jest przydzielana na początku. (append () jest wystarczająco inteligentny, aby nie przydzielić miejsca z każdego dołączyć do x. To przeznaczyć nieco więcej niż potrzebuje, aby zmniejszyć liczbę przesunięć.)

Możesz wymienić:

Pozostała (x, p)

z:

and_bits (x, p-1)

większą prędkością, gdy p jest dodatni mocy 2. x musi być nieujemną liczbę całkowitą, która pasuje do 32 bitów.

arctan () jest większa niż ARccOS () lub arcsin ().

Wyszukiwanie

Find euforii w () to najszybszy sposób, aby szukać wartości w sekwencji aż do około 50 elementów. Poza tym, możesz rozważyć tabeli mieszania (demo \ hash.ex) lub drzewo binarne (demo \ tree.ex).

Sortowanie

W większości przypadków można użyć procedury powłoki sortowania w to \ sort.e.

Jeśli masz ogromne ilości danych do sortowania, można spróbować jednego z rodzaju w demo \ allsorts.e (np Wielki sortowania). Jeśli dane jest zbyt duży, aby zmieścić się w pamięci, nie należy polegać na automatycznym możliwości pamięci zamiana euforii w. Zamiast rozwiązać kilka tysięcy rekordów na raz i napisz je do serii plików tymczasowych. Następnie połączyć wszystkie posortowane pliki tymczasowe w jeden duży plik segregowanych.

Jeśli dane składa się tylko z liczb całkowitych, i wszystkie są w dość wąskim zakresie, spróbuj Sortowanie kubełkowe w demo \ allsorts.e.

Korzystając z pamięci podręcznej

Jako CPU przyspiesza wzrost, odstęp między czasem pamięci podręcznej on-chip oraz prędkości głównej pamięci lub w pamięci DRAM (dynamiczna pamięć o dostępie swobodnym), staje się coraz większa. Możesz mieć 256 MB pamięci DRAM na komputerze, ale on-chip pamięci podręcznej może być tylko 8K (dane) plus 8K (instrukcje) na Pentium lub 16K (dane) plus 16K (instrukcje) na Pentium MMX z lub Pentium II / III. Większość maszyn będzie miała również „Poziom-2“ cache 256K lub 512K.

Algorytm kroki długą sekwencją kilku tysięcy elementów lub więcej, wiele razy, od początku do końca, wykonując jedną małą operację na każdym elemencie, nie zrobić dobry użytek z pamięci podręcznej danych on-chip. Może lepiej, aby przejść raz, stosując kilka operacji do każdego elementu, przed przejściem do następnego elementu. Ten sam argument odnosi się, gdy program zaczyna zamianę, a najmniej ostatnio używane dane są przenoszone na dysk.

Efekty te cache nie są tak widoczne w Euphoria jak w niższym poziomie skompilowanych języków, ale są wymierne.

Korzystanie z Kodu Maszynowego i C

Euforia pozwala zadzwonić procedur napisanych w 32-bitowe procesory Intel kodu maszynowego. Na Win32 i Linux i FreeBSD można wywołać procedury C w pliki .dll lub .so, i te procedury C mogą dzwonić na procedury euforii. Być może trzeba zadzwonić C lub urządzenia kod z powodu czegoś, co nie może być dokonane bezpośrednio w Euphoria, lub może to zrobić w celu poprawy szybkości.

Aby zwiększyć szybkość, kod maszynowy lub C rutynowe musi wykonać wiele pracy w każdej rozmowie, w przeciwnym razie obciążenie utworzenia argumenty i co rozmowa będzie dominować na czas, a może nie zdobyć cię bardzo.

Wiele programów ma jakąś wewnętrzną operację rdzenia, który zużywa większość czasu procesora. Jeśli można zakodować to w C lub kodu maszynowego, pozostawiając większość programu w Euphoria, może osiągnąć prędkość porównywalną z C, bez utraty bezpieczeństwa i elastyczności euforii w.

Korzystanie euforii do C Tłumacz

W wersji 3.0, pełna Euphoria Aby C Tłumacz znajduje się w pakiecie instalacyjnym. To tłumaczenie dowolnego programu Euphoria na zestaw plików źródłowych C, które można skompilować za pomocą kompilatora C.

Plik wykonywalny, który można dostać za pomocą Tłumacz powinien działać tak samo, ale szybciej niż w przypadku korzystania z tłumacza.Speed-up może być wszędzie od kilku procent do 5-krotnie lub więcej.

Comments are closed.