Efektywność algorytmiczna
W informatyce efektywność algorytmiczna jest właściwością algorytmu , która odnosi się do ilości zasobów obliczeniowych wykorzystywanych przez algorytm. Algorytm musi zostać przeanalizowany , aby określić wykorzystanie zasobów, a efektywność algorytmu można zmierzyć na podstawie wykorzystania różnych zasobów. Efektywność algorytmiczna może być traktowana jako analogiczna do produktywności inżynierskiej dla powtarzalnego lub ciągłego procesu.
Aby uzyskać maksymalną wydajność, pożądane jest zminimalizowanie zużycia zasobów. Jednak różnych zasobów, takich jak czasowa i przestrzenna , nie można porównywać bezpośrednio, więc to, który z dwóch algorytmów jest uważany za bardziej wydajny, często zależy od tego, która miara wydajności jest uważana za najważniejszą.
Na przykład sortowanie bąbelkowe i sortowanie czasowe to algorytmy sortowania listy elementów od najmniejszego do największego. Sortowanie bąbelkowe sortuje listę w proporcjonalnym do liczby elementów do kwadratu ( , notacja O ), ale ilości dodatkowej pamięci która jest względem ( Timsort sortuje listę w czasie liniowo do ilości pomnożonej przez jej logarytm) na długości listy ( wymagania dotyczące liniowe długości z listy ( ). Jeśli duże listy muszą być sortowane z dużą szybkością dla danej aplikacji, lepszym wyborem jest timsort; jeśli jednak ważniejsze jest zminimalizowanie zużycia pamięci przez sortowanie, lepszym wyborem jest sortowanie bąbelkowe.
Tło
Znaczenie wydajności w odniesieniu do czasu zostało podkreślone przez Adę Lovelace w 1843 r. w odniesieniu do mechanicznego silnika analitycznego Charlesa Babbage'a :
„W prawie każdym obliczeniu możliwa jest wielka różnorodność układów następstwa procesów, a na ich wybór dla celów silnika obliczeniowego muszą wpływać różne względy. Jednym z zasadniczych celów jest wybór takiego układu, który będzie dążył do zredukowania do minimum czasu niezbędnego do wykonania obliczeń”
Wczesne komputery elektroniczne miały zarówno ograniczoną prędkość , jak i ograniczoną pamięć o dostępie swobodnym . W związku z tym wymiana czasoprzestrzenna . Zadanie pamięci lub powolnego algorytmu zużywającego mało pamięci. Kompromis inżynierski polegał wówczas na zastosowaniu najszybszego algorytmu, który zmieściłby się w dostępnej pamięci.
Nowoczesne komputery są znacznie szybsze niż pierwsze komputery i mają znacznie większą ilość dostępnej pamięci ( gigabajty zamiast kilobajtów ). Niemniej jednak Donald Knuth podkreślił, że wydajność jest nadal ważnym czynnikiem:
„W uznanych dyscyplinach inżynierskich łatwo osiągalna poprawa o 12% nigdy nie jest uważana za marginalną i uważam, że ten sam punkt widzenia powinien dominować w inżynierii oprogramowania”
Przegląd
Algorytm jest uważany za wydajny, jeśli jego zużycie zasobów, znane również jako koszt obliczeniowy, jest na akceptowalnym poziomie lub poniżej niego. Z grubsza mówiąc, „akceptowalny” oznacza: będzie działać w rozsądnym czasie lub miejscu na dostępnym komputerze, zazwyczaj jako funkcja rozmiaru danych wejściowych. Od lat pięćdziesiątych XX wieku komputery odnotowały dramatyczny wzrost zarówno dostępnej mocy obliczeniowej, jak i dostępnej ilości pamięci, więc obecne akceptowalne poziomy byłyby nie do przyjęcia nawet 10 lat temu. W rzeczywistości, dzięki przybliżonemu podwajaniu mocy komputerów co 2 lata , zadania, które są akceptowalnie wydajne na nowoczesnych smartfonach i systemach wbudowanych, mogły być niedopuszczalnie nieefektywne dla serwerów przemysłowych 10 lat temu.
Producenci komputerów często wprowadzają nowe modele, często o wyższej wydajności . Koszty oprogramowania mogą być dość wysokie, więc w niektórych przypadkach najprostszym i najtańszym sposobem uzyskania wyższej wydajności może być po prostu zakup szybszego komputera, pod warunkiem, że jest on zgodny z istniejącym komputerem.
Istnieje wiele sposobów mierzenia zasobów wykorzystywanych przez algorytm: dwie najczęstsze miary to szybkość i użycie pamięci; inne miary mogą obejmować prędkość transmisji, tymczasowe użycie dysku, długoterminowe użycie dysku, zużycie energii, całkowity koszt posiadania , czas reakcji na bodźce zewnętrzne itp. Wiele z tych miar zależy od wielkości danych wejściowych do algorytmu, tj. ilość danych do przetworzenia. Mogą również zależeć od sposobu ułożenia danych; na przykład niektóre algorytmy sortowania działają słabo na danych, które są już posortowane lub posortowane w odwrotnej kolejności.
W praktyce istnieją inne czynniki, które mogą wpływać na wydajność algorytmu, takie jak wymagania dotyczące dokładności i/lub niezawodności. Jak wyszczególniono poniżej, sposób implementacji algorytmu może również mieć znaczący wpływ na rzeczywistą wydajność, chociaż wiele aspektów tego odnosi się do kwestii optymalizacji .
Analiza teoretyczna
W teoretycznej analizie algorytmów normalną praktyką jest szacowanie ich złożoności w sensie asymptotycznym. Najczęściej używaną notacją do opisania zużycia zasobów lub „złożoności” jest notacja Big O Donalda Knutha , reprezentująca złożoność algorytmu jako funkcję wielkości danych wejściowych. . Notacja dużego O jest asymptotyczną miarą złożoności funkcji, gdzie wymagany czas dla algorytmu jest proporcjonalny do pomijając wyrażenia niższego rzędu , przyczyniają się mniej niż wzrostu funkcji jako rośnie dowolnie duże . To oszacowanie może być mylące, gdy , ale generalnie jest wystarczająco dokładne, gdy jest jest asymptotyczna. Na przykład sortowanie bąbelkowe może być szybsze niż sortowanie przez scalanie, gdy ma być posortowanych tylko kilka elementów; jednak każda implementacja prawdopodobnie spełni wymagania dotyczące wydajności dla małej listy. Zazwyczaj programiści są zainteresowani algorytmami, które efektywnie skalują się do dużych rozmiarów danych wejściowych, a sortowanie przez scalanie jest preferowane zamiast sortowania bąbelkowego w przypadku list o długości spotykanych w większości programów intensywnie korzystających z danych.
Niektóre przykłady notacji Big O zastosowanej do asymptotycznej złożoności czasowej algorytmów obejmują:
Notacja | Nazwa | Przykłady |
---|---|---|
stały | Znalezienie mediany z posortowanej listy pomiarów; Korzystanie z tabeli przeglądowej o stałym rozmiarze ; Używanie odpowiedniej funkcji skrótu do wyszukiwania elementu. | |
logarytmiczny | Znajdowanie elementu w posortowanej tablicy za pomocą wyszukiwania binarnego lub zrównoważonego drzewa wyszukiwania oraz wszystkich operacji na stercie dwumianowej . | |
liniowy | Znalezienie elementu na nieposortowanej liście lub zniekształconym drzewie (najgorszy przypadek) lub w nieposortowanej tablicy; Dodawanie dwóch n -bitowych liczb całkowitych metodą ripple carry . | |
liniowej , logliniowej lub quasiliniowej | Wykonywanie szybkiej transformaty Fouriera ; sortowanie sterty , sortowanie szybkie ( przypadek najlepszy i średni ) lub sortowanie przez scalanie | |
kwadratowy | Mnożenie dwóch n -cyfrowych liczb za pomocą prostego algorytmu ; sortowanie bąbelkowe (najgorszy przypadek lub naiwna implementacja), sortowanie skorupowe , sortowanie szybkie ( najgorszy przypadek ), sortowanie przez wybór lub sortowanie przez wstawianie | |
wykładniczy | Znalezienie optymalnego (nieprzybliżonego ) rozwiązania problemu komiwojażera z wykorzystaniem programowania dynamicznego ; określenie, czy dwie instrukcje logiczne są równoważne przy użyciu wyszukiwania siłowego |
Benchmarking: pomiar wydajności
W przypadku nowych wersji oprogramowania lub w celu zapewnienia porównań z konkurencyjnymi systemami czasami stosuje się testy porównawcze , które pomagają w ocenie względnej wydajności algorytmów. Na przykład, jeśli zostanie stworzony nowy algorytm sortowania , można go porównać z jego poprzednikami, aby upewnić się, że przynajmniej jest wydajny jak poprzednio ze znanymi danymi, biorąc pod uwagę wszelkie ulepszenia funkcjonalne. Benchmarki mogą być wykorzystywane przez klientów podczas porównywania różnych produktów alternatywnych dostawców w celu oszacowania, który produkt najlepiej spełni ich specyficzne wymagania pod względem funkcjonalności i wydajności. Na przykład w komputerów mainframe niektóre zastrzeżone produkty sortujące niezależnych firm programistycznych, takie jak Syncsort , konkurują o szybkość z produktami głównych dostawców, takich jak IBM .
Niektóre testy porównawcze umożliwiają na przykład analizę porównującą względną szybkość różnych języków kompilowanych i interpretowanych, a gra porównawcza języka komputerowego porównuje wydajność implementacji typowych problemów programistycznych w kilku językach programowania.
Nawet tworzenie testów porównawczych „ zrób to sam ” może wykazać względną wydajność różnych języków programowania przy użyciu różnych kryteriów określonych przez użytkownika. Jest to dość proste, jak pokazuje na przykładzie „Podsumowanie występów w dziewięciu językach” autorstwa Christophera W. Cowell-Shaha.
Obawy dotyczące wdrażania
Kwestie implementacyjne mogą również mieć wpływ na wydajność, takie jak wybór języka programowania lub sposób, w jaki algorytm jest faktycznie kodowany, lub wybór kompilatora dla określonego języka, lub stosowane opcje kompilacji , a nawet sposób obsługi używany system . W wielu przypadkach język zaimplementowany przez tłumacza może być znacznie wolniejszy niż język zaimplementowany przez kompilator. Zobacz artykuły na temat kompilacji just-in-time i języków interpretowanych .
Istnieją inne czynniki, które mogą wpływać na kwestie czasu lub przestrzeni, ale które mogą być poza kontrolą programisty; obejmują one wyrównanie danych , ziarnistość danych , lokalizację pamięci podręcznej , spójność pamięci podręcznej , wyrzucanie elementów bezużytecznych , równoległość na poziomie instrukcji , wielowątkowość (na poziomie sprzętu lub oprogramowania), jednoczesną wielozadaniowość i wywołania podprogramów .
Niektóre procesory mają możliwości przetwarzania wektorowego , co pozwala pojedynczej instrukcji na działanie na wielu operandach ; korzystanie z tych możliwości może być łatwe lub trudne dla programisty lub kompilatora. Algorytmy przeznaczone do przetwarzania sekwencyjnego mogą wymagać całkowitego przeprojektowania w celu wykorzystania przetwarzania równoległego lub mogą być łatwo rekonfigurowane. Wraz ze obliczeń równoległych i rozproszonych pod koniec 2010 roku, coraz więcej inwestuje się w wydajne interfejsy API wysokiego poziomu dla równoległych i rozproszonych systemów obliczeniowych, takich jak CUDA , TensorFlow , Hadoop , OpenMP i MPI .
Innym problemem, który może pojawić się podczas programowania, jest to, że procesory kompatybilne z tym samym zestawem instrukcji (takie jak x86-64 lub ARM ) mogą implementować instrukcje na różne sposoby, tak że instrukcje, które są stosunkowo szybkie w niektórych modelach, mogą być stosunkowo wolne w innych modelach . To często stanowi wyzwanie dla optymalizacji kompilatorów , które muszą mieć dużą wiedzę na temat konkretnego procesora i innego sprzętu dostępnego w miejscu docelowym kompilacji, aby jak najlepiej zoptymalizować program pod kątem wydajności. W skrajnym przypadku kompilator może zostać zmuszony do emulacji instrukcji nieobsługiwanych na docelowej platformie kompilacji, zmuszając go do wygenerowania kodu lub połączenia wywołania biblioteki zewnętrznej w celu uzyskania wyniku, który w innym przypadku byłby nieobliczalny na tej platformie, nawet jeśli jest obsługiwany natywnie i bardziej wydajne sprzętowo na innych platformach. Dzieje się tak często w systemach wbudowanych w odniesieniu do arytmetyki zmiennoprzecinkowej , gdzie małe mikrokontrolery o niskim poborze mocy często nie mają sprzętowego wsparcia dla arytmetyki zmiennoprzecinkowej, a zatem wymagają kosztownych obliczeniowo procedur programowych do wykonywania obliczeń zmiennoprzecinkowych.
Miary zużycia zasobów
Miary są zwykle wyrażane jako funkcja wielkości danych wejściowych .
Dwa najczęstsze środki to:
- Czas : ile czasu zajmuje wykonanie algorytmu?
- Przestrzeń : ile pamięci roboczej (zwykle RAM) potrzebuje algorytm? Ma to dwa aspekty: ilość pamięci potrzebnej kodowi (wykorzystanie przestrzeni pomocniczej) oraz ilość pamięci potrzebnej na dane, na których działa kod (wewnętrzne wykorzystanie przestrzeni).
W przypadku komputerów zasilanych baterią (np. laptopy i smartfony ) lub w przypadku bardzo długich/dużych obliczeń (np. superkomputery ) inne interesujące miary to:
- Bezpośredni pobór mocy : energia potrzebna bezpośrednio do obsługi komputera.
- Pośrednie zużycie energii : moc potrzebna do chłodzenia, oświetlenia itp.
Od 2018 r. zużycie energii rośnie jako ważny wskaźnik dla zadań obliczeniowych wszystkich typów i we wszystkich skalach, od wbudowanych urządzeń Internetu rzeczy, przez urządzenia system-on-chip, po farmy serwerów . Tendencja ta jest często określana mianem zielonej informatyki .
W niektórych przypadkach istotne mogą być również mniej powszechne miary wydajności obliczeniowej:
- Rozmiar transmisji : przepustowość może być czynnikiem ograniczającym. Kompresję danych można wykorzystać do zmniejszenia ilości przesyłanych danych. Wyświetlenie obrazu lub obrazu (np. logo Google ) może spowodować przesłanie dziesiątek tysięcy bajtów (w tym przypadku 48 KB) w porównaniu z przesłaniem sześciu bajtów tekstu „Google”. Jest to ważne w przypadku zadań obliczeniowych związanych z wejściem/wyjściem .
- Miejsce zewnętrzne : potrzebne miejsce na dysku lub innym zewnętrznym urządzeniu pamięci; może to być tymczasowe przechowywanie podczas wykonywania algorytmu lub może to być przechowywanie długoterminowe, które należy przenieść do wykorzystania w przyszłości.
- Czas odpowiedzi ( opóźnienie ): jest to szczególnie istotne w aplikacjach działających w czasie rzeczywistym, kiedy system komputerowy musi szybko reagować na jakieś zewnętrzne zdarzenia .
- Całkowity koszt posiadania : szczególnie, jeśli komputer jest przeznaczony do jednego konkretnego algorytmu.
Czas
Teoria
Przeanalizuj algorytm, zwykle używając analizy złożoności czasowej , aby uzyskać oszacowanie czasu działania w funkcji rozmiaru danych wejściowych. Wynik jest zwykle wyrażany za pomocą notacji Big O. Jest to przydatne do porównywania algorytmów, zwłaszcza gdy ma być przetwarzana duża ilość danych. Potrzebne są bardziej szczegółowe szacunki, aby porównać wydajność algorytmu, gdy ilość danych jest niewielka, chociaż prawdopodobnie będzie to miało mniejsze znaczenie. algorytmów zawierających przetwarzanie równoległe może być trudniejsza .
Ćwiczyć
Użyj testu porównawczego , aby określić czas użycia algorytmu. Wiele języków programowania ma dostępną funkcję, która zapewnia wykorzystanie czasu procesora . W przypadku długotrwałych algorytmów czas, który upłynął, może być również interesujący. Wyniki należy generalnie uśrednić z kilku testów.
Profilowanie oparte na uruchamianiu może być bardzo wrażliwe na konfigurację sprzętową i możliwość jednoczesnego uruchamiania innych programów lub zadań w środowisku wieloprocesorowym i wieloprogramowym .
Ten rodzaj testu zależy również w dużej mierze od wyboru konkretnego języka programowania, kompilatora i opcji kompilatora, więc porównywane algorytmy muszą być zaimplementowane w tych samych warunkach.
Przestrzeń
Ta sekcja dotyczy wykorzystania zasobów pamięci ( rejestry , pamięć podręczna , pamięć RAM , pamięć wirtualna , pamięć pomocnicza ) podczas wykonywania algorytmu. Jeśli chodzi o powyższą analizę czasu, przeanalizuj algorytm, zwykle używając analizy złożoności przestrzeni , aby uzyskać oszacowanie potrzebnej pamięci czasu wykonywania jako funkcji wielkości danych wejściowych. Wynik jest zwykle wyrażany za pomocą notacji Big O.
Należy wziąć pod uwagę maksymalnie cztery aspekty wykorzystania pamięci:
- Ilość pamięci potrzebna do przechowywania kodu algorytmu.
- Ilość pamięci potrzebnej na dane wejściowe .
- Ilość pamięci potrzebnej do przechowywania dowolnych danych wyjściowych .
- Niektóre algorytmy, takie jak sortowanie, często zmieniają kolejność danych wejściowych i nie wymagają dodatkowego miejsca na dane wyjściowe. Ta właściwość jest nazywana operacją „ w miejscu ”.
- Ilość pamięci potrzebnej jako przestrzeń robocza podczas obliczeń.
- Obejmuje to zmienne lokalne i wszelkie miejsce na stosie wymagane przez procedury wywoływane podczas obliczeń; ta przestrzeń stosu może być istotna dla algorytmów wykorzystujących techniki rekurencyjne .
Wczesne komputery elektroniczne i wczesne komputery domowe miały stosunkowo niewielką ilość pamięci roboczej. Na przykład elektroniczny kalkulator automatycznego przechowywania opóźnień (EDSAC) z 1949 r. Miał maksymalną pamięć roboczą wynoszącą 1024 17-bitowych słów, podczas gdy Sinclair ZX80 z 1980 r . Był początkowo wyposażony w 1024 8-bitowych bajtów pamięci roboczej. Pod koniec 2010 roku komputery osobiste miały zwykle od 4 do 32 GB pamięci RAM, co stanowi wzrost o ponad 300 milionów razy więcej pamięci.
Hierarchia buforowania i pamięci
Obecne komputery mogą mieć stosunkowo duże ilości pamięci (prawdopodobnie gigabajty), więc konieczność wciśnięcia algorytmu do ograniczonej ilości pamięci jest znacznie mniejszym problemem niż kiedyś. Ale obecność czterech różnych kategorii pamięci może być znacząca:
- Rejestry procesora , najszybsza technologia pamięci komputera z najmniejszą ilością miejsca do przechowywania. Większość bezpośrednich obliczeń na nowoczesnych komputerach odbywa się z operandami źródłowymi i docelowymi w rejestrach przed aktualizacją do pamięci podręcznej, pamięci głównej i pamięci wirtualnej, jeśli to konieczne. W rdzeniu procesora dostępne są rejestry rzędu setek bajtów lub mniej, chociaż plik rejestru może zawierać więcej rejestrów fizycznych niż rejestrów architektonicznych zdefiniowanych w architekturze zestawu instrukcji.
- Pamięć podręczna jest drugą najszybszą i drugą najmniejszą pamięcią dostępną w hierarchii pamięci. Pamięci podręczne są obecne w procesorach, procesorach graficznych, dyskach twardych i zewnętrznych urządzeniach peryferyjnych i zwykle są implementowane w statycznej pamięci RAM . Pamięci podręczne są wielopoziomowe ; niższe poziomy są większe, wolniejsze i zwykle współdzielone przez rdzenie procesorów w procesorach wielordzeniowych . Aby przetwarzać operandy w pamięci podręcznej, jednostka przetwarzająca musi pobrać dane z pamięci podręcznej, wykonać operację w rejestrach i ponownie zapisać dane do pamięci podręcznej. Działa to z prędkościami porównywalnymi (około 2-10 razy wolniejszymi) z jednostką arytmetyczną procesora lub GPU lub jednostką zmiennoprzecinkową, jeśli znajduje się w pamięci podręcznej L1 . Jest około 10 razy wolniejszy w przypadku chybienia w pamięci podręcznej L1 i musi zostać pobrany z pamięci podręcznej L2 i do niej zapisany , a kolejne 10 razy wolniejszy w przypadku chybienia w pamięci podręcznej L2 i musi zostać pobrany z pamięci podręcznej L3 , jeśli obecny.
- Główna pamięć fizyczna jest najczęściej realizowana w dynamicznej pamięci RAM (DRAM). Pamięć główna jest znacznie większa (zwykle gigabajty w porównaniu do ≈8 megabajtów ) niż pamięć podręczna procesora L3, a opóźnienia odczytu i zapisu są zazwyczaj 10-100 razy wolniejsze. Od 2018 roku pamięć RAM jest coraz częściej wdrażana na chipie procesorów, jako pamięć procesora lub karty graficznej.
- Pamięć wirtualna jest najczęściej implementowana jako dodatkowa pamięć masowa , taka jak dysk twardy , i jest rozszerzeniem hierarchii pamięci , która ma znacznie większą przestrzeń dyskową, ale znacznie większe opóźnienie, zwykle około 1000 razy wolniejsze niż brak pamięci podręcznej dla wartości w pamięci RAM . Chociaż pierwotnie motywowano ją do stworzenia wrażenia większej ilości dostępnej pamięci niż w rzeczywistości, pamięć wirtualna jest ważniejsza we współczesnym użyciu ze względu na kompromis czasoprzestrzenny i umożliwienie korzystania z maszyn wirtualnych . Braki w pamięci podręcznej pamięci głównej nazywane są błędami strony i powodują ogromne obniżenie wydajności programów.
Algorytm, którego zapotrzebowanie na pamięć zmieści się w pamięci podręcznej, będzie znacznie szybszy niż algorytm mieszczący się w pamięci głównej, co z kolei będzie znacznie szybsze niż algorytm, który musi uciekać się do pamięci wirtualnej. Z tego powodu zasady zastępowania pamięci podręcznej są niezwykle ważne dla obliczeń o wysokiej wydajności, podobnie jak programowanie uwzględniające pamięć podręczną i wyrównywanie danych . Aby jeszcze bardziej skomplikować problem, niektóre systemy mają do trzech poziomów pamięci podręcznej, z różnymi efektywnymi prędkościami. Różne systemy będą miały różne ilości tych różnych typów pamięci, więc wpływ potrzeb pamięci algorytmu może się znacznie różnić w zależności od systemu.
We wczesnych latach obliczeń elektronicznych, jeśli algorytm i jego dane nie mieściły się w pamięci głównej, nie można było użyć algorytmu. Obecnie użycie pamięci wirtualnej wydaje się zapewniać dużo pamięci, ale kosztem wydajności. Jeśli algorytm i jego dane zmieszczą się w pamięci podręcznej, to można uzyskać bardzo dużą prędkość; w tym przypadku minimalizacja przestrzeni pomoże również zminimalizować czas. Nazywa się to zasadą lokalności i można ją podzielić na lokalność odniesienia , lokalność przestrzenną i lokalność czasową . Algorytm, który nie zmieści się całkowicie w pamięci podręcznej, ale który wykazuje lokalność odniesienia, może działać dość dobrze.
Krytyka obecnego stanu programowania
- David May FRS, brytyjski informatyk , a obecnie profesor informatyki na Uniwersytecie w Bristolu oraz założyciel i dyrektor techniczny firmy XMOS Semiconductor , uważa , że jednym z problemów jest poleganie na prawie Moore'a w celu rozwiązania nieefektywności. Udoskonalił „alternatywę” dla prawa Moore'a ( prawo Maya ), które brzmi następująco:
- Wydajność
oprogramowania zmniejsza się o połowę co 18 miesięcy, rekompensując to prawem Moore'a
. zestawy dają duże możliwości dla lepszego oprogramowania i algorytmów: Zmniejszenie liczby operacji z N × N do N × log (N) ma dramatyczny efekt, gdy N jest duże… dla N = 30 miliardów ta zmiana wynosi nawet 50 lat ulepszeń technologii.
- Autor oprogramowania Adam N. Rosenburg na swoim blogu „ Awaria komputera cyfrowego ” opisał obecny stan programowania jako zbliżający się do „horyzontu zdarzeń oprogramowania” (nawiązując do fikcyjnego „ horyzontu zdarzeń obuwia ” opisanego przez Douglasa Adamsa w jego Książka Autostopem przez Galaktykę ). Szacuje, że od lat 80. XX wieku nastąpił spadek produktywności lub „99,99999 procent jego zdolności do dostarczania towarów” o 70 dB - „Kiedy Arthur C. Clarke porównał rzeczywistość komputerową w 2001 r. Do komputera HAL 9000 w jego book 2001: A Space Odyssey , zwrócił uwagę, jak cudownie małe i potężne były komputery, ale jak rozczarowujące stało się programowanie komputerowe”.
Konkursy na najlepsze algorytmy
Następujące konkursy zapraszają do zgłaszania najlepszych algorytmów opartych na arbitralnych kryteriach ustalonych przez sędziów:
Zobacz też
- Analiza algorytmów — jak określić zasoby potrzebne algorytmowi
- Kodowanie arytmetyczne — forma kodowania entropijnego o zmiennej długości w celu wydajnej kompresji danych
- Tablica asocjacyjna — struktura danych, którą można usprawnić za pomocą drzew Patricii lub tablic Judy
- Benchmark — metoda pomiaru porównawczego czasu wykonania w określonych przypadkach
- Najlepszy, najgorszy i średni przypadek — rozważania dotyczące szacowania czasu wykonania w trzech scenariuszach
- Algorytm wyszukiwania binarnego — prosta i wydajna technika wyszukiwania posortowanych tablic
- Tabela rozgałęzień - technika zmniejszania długości ścieżki instrukcji, rozmiaru kodu maszynowego (a często także pamięci)
- Porównanie paradygmatów programowania — względy wydajności specyficzne dla paradygmatu
- Optymalizacja kompilatora — optymalizacja pochodząca z kompilatora
- Złożoność obliczeniowa operacji matematycznych
- Teoria złożoności obliczeniowej
- Wydajność komputera — wskaźniki sprzętu komputerowego
- Kompresja danych — zmniejszenie przepustowości transmisji i miejsca na dysku
- Indeks bazy danych — struktura danych, która poprawia szybkość operacji wyszukiwania danych w tabeli bazy danych
- Kodowanie entropijne — wydajne kodowanie danych z wykorzystaniem częstości występowania ciągów znaków jako kryterium podstawienia
- Wyrzucanie śmieci — automatyczne zwalnianie pamięci po użyciu
- Ekologiczne przetwarzanie danych — krok w kierunku wdrożenia „bardziej ekologicznych” technologii, zużywających mniej zasobów
- Algorytm Huffmana — algorytm wydajnego kodowania danych
- Poprawa wydajności kodu zarządzanego — Microsoft MSDN Library
- Lokalność odniesienia — w celu uniknięcia opóźnień w buforowaniu spowodowanych dostępem do pamięci innej niż lokalna
- Optymalizacja pętli
- Zarządzanie pamięcią
- Optymalizacja (informatyka)
- Analiza wydajności — metody pomiaru rzeczywistej wydajności algorytmu w czasie wykonywania
- Przetwarzanie w czasie rzeczywistym — kolejne przykłady zastosowań, w których czas ma krytyczne znaczenie
- Analiza czasu działania — oszacowanie oczekiwanych czasów działania i skalowalności algorytmu
- Jednoczesna wielowątkowość
- Algorytm sortowania § Porównanie algorytmów
- Egzekucja spekulacyjna lub Eager egzekucja
- Przewidywanie gałęzi
- Super-wątkowość
- Kod wielowątkowy — podobny do wirtualnej tabeli metod lub tabeli rozgałęzień
- Wirtualna tablica metod — tablica rozgałęzień z dynamicznie przypisywanymi wskaźnikami do rozsyłania