Piszę grę kółko i krzyżyk i używając Enuma do reprezentowania trzech wyników - lose
, draw
i win
. Pomyślałem, że będzie to lepszy styl niż użycie ciągów ("lose", "win", "draw")
do wskazania tych wartości. Ale użycie wyrażeń spowodowało, że osiągnąłem znaczący sukces.Jak używać wyrażeń w języku Python 3.4 bez znaczącego spowolnienia?
Oto minimalny przykład, w którym po prostu odwołuję się do Result.lose
lub literalnego ciągu znaków lose
.
import enum
import timeit
class Result(enum.Enum):
lose = -1
draw = 0
win = 1
>>> timeit.timeit('Result.lose', 'from __main__ import Result')
1.705788521998329
>>> timeit.timeit('"lose"', 'from __main__ import Result')
0.024598151998361573
Jest to znacznie wolniej niż po prostu odwołanie do zmiennej globalnej.
k = 12
>>> timeit.timeit('k', 'from __main__ import k')
0.02403248500195332
Moje pytania są następujące:
- wiem, że globalne wyszukiwań są znacznie wolniejsze niż lokalnych wyszukiwań w Pythonie. Ale dlaczego wyliczenia enum są jeszcze gorsze?
- Jak efektywnie używać wyliczeń bez obniżania wydajności? Przegląd Enuma okazał się całkowicie dominujący w czasie wykonywania mojego programu "kółko i krzyżyk". Możemy zapisać lokalne kopie enum w każdej funkcji lub zawinąć wszystko w klasę, ale oba te wydają się niezręczne.
Myślę, że prawdopodobnie pobieranie atrybutów jest powolne. Jeśli zrobisz coś takiego jak "lose = Result.lose", a następnie przetestujesz z 'lose', czy to lokalnym, czy globalnym, myślę, że zobaczysz wymierne przyspieszenie. – Shashank
Dzięki, że działa całkiem dobrze. Czy wiesz, dlaczego wyszukiwanie atrybutów jest o wiele wolniejsze niż wyszukiwanie globalne? Wiem, że lokale są przechowywane w macierzy o stałej długości, podczas gdy globale są w dyktacie, ale co z atrybutami? –
Nie wiem, przepraszam. I nie mogłem powiedzieć nic z pewnością bez czytania źródła CPython. Gdybym miał zgadywać, powiedziałbym, że obiekty są implementowane z asocjacyjnymi tablicami lub mapami lub czymkolwiek pod maską (tylko możliwość, nie należy traktować ich jako faktów), więc może być koszt dla algorytmu mieszania używanego na nazwach atrybutów które są jak klucze strunowe do tablicy mieszającej, ale to wszystko spekulacja. W każdym razie teraz wiesz, jak zminimalizować go w przypadku powtarzających się wyszukiwań. Lokalizacja ftw. – Shashank