Jest to w rzeczywistości głęboka kwestia, która zawiera pewne metodyczne i pragmatyczne odpowiedzi. Zakładam, że chcesz wiedzieć coś o dostępnym algorytmie (algorytmach) . Jeśli chcesz wiedzieć, który algorytm działa lepiej na danej maszynie na danych wejściowych, kontynuuj i mierz środowiska wykonawcze. Jeśli chcesz porównać jakość kompilatora dla danego algorytmu, śmiało i zmierz czasy działania. Aby dowiedzieć się czegoś o algorytmie, nie rób tego.
Pozwól mi najpierw podać kilka powodów, dla których używanie środowisk wykonawczych nie jest dobrym pomysłem.
- Ogólne środowiska
wykonawcze mierzone za pomocą jednego języka i jednego kompilatora na jednym komputerze mają niewielkie znaczenie, jeśli zmienisz dowolny komponent. Nawet nieznacznie różne implementacje tego samego algorytmu mogą działać inaczej, ponieważ uruchamiasz pewną optymalizację kompilatora w przypadku, ale nie w innym.
- Prognozowanie
Masz więc kilka środowisk uruchomieniowych dla niektórych danych wejściowych. Co to mówi o czasie wykonywania niektórych innych danych wejściowych? Ogólnie nic.
- Znaczenie
Zwykle nie porównujesz wszystkich danych wejściowych (o pewnym rozmiarze), co natychmiast ogranicza twoją zdolność porównywania algorytmów: może twój zestaw testowy wywołał najgorszy przypadek w jednym i najlepszy przypadek w drugim algorytmie? A może twoje dane wejściowe były zbyt małe, aby pokazać zachowanie w czasie wykonywania .
- Pomiary Dobrze
mierzone czasy wykonania nie są trywialne. Czy jest JIT? Czy było spór, tj. Czy odliczasz czas, gdy algorytm nawet nie działał? Czy możesz odtworzyć dokładnie ten sam stan komputera dla innego przebiegu (innego algorytmu), w szczególności dla równoległych procesów i pamięci podręcznych? Jak radzone jest opóźnienie pamięci?
Mam nadzieję, że przekonały cię, że środowiska wykonawcze są okropną miarą do porównywania algorytmów i że potrzebna jest ogólna, abstrakcyjna metoda badania środowiska uruchomieniowego algorytmu.
Do drugiej części pytania. Dlaczego korzystamy z porównań lub podobnych operacji elementarnych?
Zdolność analityczna
Zakładając, że chcesz przeprowadzić analizę formalną, musisz być w stanie to zrobić. Liczenie pojedynczych stwierdzeń jest bardzo techniczne, a czasem nawet trudne; mimo to niektórzy to robią (np. Knuth). Liczenie tylko niektórych instrukcji - dominujących w środowisku wykonawczym - jest łatwiejsze. Z tego samego powodu często „tylko” badamy (górne granice) środowisko wykonawcze w najgorszym przypadku.
Dominacja
Wybrana operacja dominuje w środowisku wykonawczym. Nie oznacza to, że wnosi najwięcej czasu wykonywania - porównania wyraźnie nie, np. W Quicksort podczas sortowania liczb całkowitych wielkości słowa. Ale są one wykonywane najczęściej , więc licząc je, liczysz, jak często uruchamiane są najczęściej wykonywane części algorytmu. W związku z tym twój asymptotyczny czas pracy jest proporcjonalny do liczby dominujących operacji elementarnych. Właśnie dlatego wygodnie posługujemy się notacją Landau i słowem „środowisko wykonawcze”, mimo że liczymy tylko porównania.
Pamiętaj, że przydatne może być policzenie więcej niż jednej operacji. Na przykład niektóre warianty Quicksort wymagają więcej porównań, ale mniej swapów niż inne (średnio).
Jeśli warto, po zapoznaniu się z całą teorią, warto ponownie sprawdzić środowiska wykonawcze, aby sprawdzić, czy prognozy przedstawione przez teorię są prawidłowe. Jeśli nie są, twoja teoria nie jest przydatna (w praktyce) i musi zostać rozszerzona. Hierarchia pamięci jest jedną z pierwszych rzeczy, które zdajesz sobie sprawę, że są ważne, ale brakuje ich w podstawowych analizach.