Niektóre punkty bazowe:
- Wywołania metod w języku Python są „drogie” ze względu na ich interpretowaną naturę . Teoretycznie, jeśli twój kod jest wystarczająco prosty, rozbicie kodu w Pythonie ma negatywny wpływ oprócz czytelności i ponownego użycia ( co jest dużym zyskiem dla programistów, a nie dla użytkowników ).
- Zasada pojedynczej odpowiedzialności (SRP) zapewnia czytelność kodu, jest łatwiejsza do testowania i utrzymania.
- Projekt ma specjalny rodzaj tła, w którym chcemy czytelnego kodu, testów i wydajności czasowej.
Na przykład taki kod, który wywołuje kilka metod (x4), jest wolniejszy niż następujący, który jest tylko jedną.
from operator import add
class Vector:
def __init__(self,list_of_3):
self.coordinates = list_of_3
def move(self,movement):
self.coordinates = list( map(add, self.coordinates, movement))
return self.coordinates
def revert(self):
self.coordinates = self.coordinates[::-1]
return self.coordinates
def get_coordinates(self):
return self.coordinates
## Operation with one vector
vec3 = Vector([1,2,3])
vec3.move([1,1,1])
vec3.revert()
vec3.get_coordinates()
W porównaniu z tym:
from operator import add
def move_and_revert_and_return(vector,movement):
return list( map(add, vector, movement) )[::-1]
move_and_revert_and_return([1,2,3],[1,1,1])
Jeśli mam zrównoważyć coś takiego, to dość obiektywnie tracę wydajność. Umysł to tylko przykład; mój projekt ma kilka mini rutyn z matematyką takich jak ta - Chociaż praca z nimi jest o wiele łatwiejsza, nasi profilerzy nie lubią tego.
Jak i gdzie przyjmujemy SRP bez uszczerbku dla wydajności w Pythonie, ponieważ jego implementacja bezpośrednio na niego wpływa?
Czy istnieją obejścia, takie jak jakiś procesor wstępny, który umieszcza rzeczy w linii do wydania?
A może Python po prostu słabo radzi sobie z rozkładem kodu?
python
performance
single-responsibility
methods
lucasgcb
źródło
źródło
Odpowiedzi:
Niestety tak, Python działa powoli i istnieje wiele anegdot na temat ludzi drastycznie zwiększających wydajność poprzez wstawianie funkcji i powodowanie, że ich kod jest brzydki.
Istnieje obejście, Cython, który jest skompilowaną wersją Pythona i jest znacznie szybszy.
- Edytuj Chciałem tylko odnieść się do niektórych komentarzy i innych odpowiedzi. Chociaż ich ciąg nie jest może specyficzny dla Pythona. ale bardziej ogólna optymalizacja.
Nie optymalizuj, dopóki nie pojawi się problem, a następnie nie będziesz szukać wąskich gardeł
Ogólnie dobra rada. Zakłada się jednak, że „normalny” kod jest zwykle wydajny. Nie zawsze tak jest. Poszczególne języki i frameworki mają swoje osobliwości. W tym przypadku wywołania funkcji.
To tylko kilka milisekund, inne rzeczy będą wolniejsze
Jeśli uruchamiasz swój kod na silnym komputerze stacjonarnym, prawdopodobnie nie obchodzi Cię to, dopóki kod pojedynczego użytkownika zostanie wykonany w ciągu kilku sekund.
Ale kod biznesowy zwykle działa dla wielu użytkowników i wymaga więcej niż jednego komputera do obsługi obciążenia. Jeśli kod działa dwa razy szybciej, oznacza to, że możesz mieć dwa razy większą liczbę użytkowników lub połowę liczby komputerów.
Jeśli posiadasz swoje maszyny i centrum danych, generalnie masz duży zapas mocy procesora. Jeśli twój kod działa trochę wolniej, możesz go wchłonąć, przynajmniej do momentu, gdy będziesz musiał kupić drugą maszynę.
W dzisiejszych czasach przetwarzania w chmurze, gdzie używasz tylko dokładnie takiej mocy obliczeniowej, jakiej potrzebujesz, i więcej, nie ma bezpośredniego kosztu dla niewykonalnego kodu.
Poprawa wydajności może radykalnie obniżyć główny koszt działalności w chmurze, a wydajność naprawdę powinna być na pierwszym miejscu.
źródło
Wiele potencjalnych problemów z wydajnością nie jest tak naprawdę problemem w praktyce. Podniesiony przez ciebie problem może być jednym z nich. W języku narodowym nazywamy martwienie się tymi problemami bez dowodu, że są to problemy przedwczesnej optymalizacji.
Jeśli piszesz interfejs dla usługi sieci Web, wywołania funkcji nie będą miały istotnego wpływu na wydajność, ponieważ koszt wysłania danych przez sieć znacznie przekracza czas potrzebny na wywołanie metody.
Jeśli piszesz wąską pętlę, która odświeża ekran wideo sześćdziesiąt razy na sekundę, może to mieć znaczenie. Ale w tym momencie twierdzę, że masz większe problemy, jeśli próbujesz użyć do tego Pythona, zadanie, do którego prawdopodobnie Python nie jest odpowiedni.
Jak zawsze dowiadujesz się, jak mierzyć. Uruchom profil wydajności lub niektóre liczniki czasu w kodzie. Sprawdź, czy to prawdziwy problem w praktyce.
Zasada jednolitej odpowiedzialności nie jest prawem ani mandatem; jest to wytyczna lub zasada. Projektowanie oprogramowania zawsze polega na kompromisach; nie ma absolutów. Często zdarza się, że zmniejsza się czytelność i / lub łatwość utrzymania prędkości, więc może być konieczne poświęcenie SRP na ołtarzu wydajności. Ale nie rób tego, chyba że wiesz, że masz problem z wydajnością.
źródło
Po pierwsze, kilka wyjaśnień: Python jest językiem. Istnieje kilka różnych interpretatorów, które mogą wykonywać kod napisany w języku Python. Implementacja referencyjna (CPython) jest zwykle tym, do której się odwołuje się, gdy ktoś mówi o „Python” tak, jakby to była implementacja, ale ważne jest, aby być precyzyjnym, gdy mówi się o charakterystyce wydajności, ponieważ mogą się one bardzo różnić między implementacjami.
Przypadek 1.) Jeśli masz czysty kod Python (<= język Python w wersji 3.5, 3.6 ma „obsługę wersji beta”), który opiera się tylko na czystych modułach Python, możesz objąć SRP wszędzie i użyć PyPy, aby go uruchomić. PyPy ( https://morepypy.blogspot.com/2019/03/pypy-v71-released-now-uses-utf-8.html ) to interpreter języka Python, który ma kompilator Just in Time (JIT) i może usunąć funkcję wywołać narzut, o ile ma wystarczająco dużo czasu na „rozgrzanie” przez śledzenie wykonanego kodu (kilka sekund IIRC). **
Jeśli jesteś ograniczony do używania interpretera CPython, możesz wyodrębnić powolne funkcje do rozszerzeń napisanych w C, które zostaną wstępnie skompilowane i nie będą obciążone żadnymi narzutami interpretera. Nadal możesz używać SRP wszędzie, ale twój kod zostanie podzielony między Python i C. To, czy jest to lepsze, czy gorsze pod względem konserwacji, niż selektywne porzucanie SRP, ale trzymanie się tylko kodu Python zależy od twojego zespołu, ale jeśli masz sekcje krytyczne pod względem wydajności kodu, będzie on niewątpliwie szybszy niż nawet najbardziej zoptymalizowany czysty kod Pythona interpretowany przez CPython. Wiele najszybszych bibliotek matematycznych Pythona korzysta z tej metody (numpy i scipy IIRC). Co jest miłym przejściem do przypadku 2 ...
Przypadek 2.) Jeśli masz kod Pythona, który używa rozszerzeń C (lub polega na bibliotekach, które używają rozszerzeń C), PyPy może, ale nie musi być przydatny, w zależności od tego, jak zostały napisane. Szczegółowe informacje można znaleźć na stronie http://doc.pypy.org/en/latest/extending.html , ale podsumowanie jest takie, że CFFI ma minimalny narzut, podczas gdy CTypes jest wolniejszy (użycie go z PyPy może być nawet wolniejsze niż CPython)
Cython ( https://cython.org/ ) to kolejna opcja, z którą nie mam tyle doświadczenia. Wspominam o tym w celu uzupełnienia, aby moja odpowiedź była „samodzielna”, ale nie wymagała żadnej wiedzy specjalistycznej. Po moim ograniczonym użyciu czułem, że musiałem ciężko pracować, aby uzyskać te same ulepszenia prędkości, które mogłem uzyskać „za darmo” z PyPy, a jeśli potrzebowałem czegoś lepszego niż PyPy, równie łatwo było napisać własne rozszerzenie C ( co ma tę zaletę, że jeśli ponownie użyję kodu w innym miejscu lub wyodrębnię jego część do biblioteki, cały mój kod może nadal działać pod dowolnym interpreterem Pythona i nie musi być uruchamiany przez Cython).
Boję się, że będę „zamknięty” w Cython, podczas gdy każdy kod napisany dla PyPy może również działać w CPython.
** Kilka dodatkowych uwag na temat PyPy w produkcji
Bądź bardzo ostrożny przy dokonywaniu wyborów, które mają praktyczny efekt „zablokowania cię” w PyPy w dużej bazie kodu. Ponieważ niektóre (bardzo popularne i przydatne) biblioteki stron trzecich nie grają dobrze z wyżej wymienionych powodów, może to powodować bardzo trudne decyzje później, jeśli zdasz sobie sprawę, że potrzebujesz jednej z tych bibliotek. Moje doświadczenie polega przede wszystkim na korzystaniu z PyPy w celu przyspieszenia niektórych (ale nie wszystkich) mikrousług, które są wrażliwe na wydajność w środowisku firmowym, gdzie dodaje ono znikomą złożoność do naszego środowiska produkcyjnego (mamy już wdrożonych wiele języków, niektóre z różnymi głównymi wersjami, takimi jak 2.7 vs 3.5 działa mimo to).
Odkryłem, że używanie zarówno PyPy, jak i CPython regularnie zmuszało mnie do pisania kodu, który opiera się tylko na gwarancjach wynikających z samej specyfikacji języka, a nie na szczegółach implementacji, które mogą ulec zmianie w dowolnym momencie. Może ci się wydawać, że myślenie o takich szczegółach stanowi dodatkowe obciążenie, ale uznałem je za cenne w moim rozwoju zawodowym i myślę, że jest „zdrowe” dla całego ekosystemu Python.
źródło