Czy jest jakaś ostateczna różnica między następującymi dwoma fragmentami kodu? Pierwsza przypisuje wartość do zmiennej w funkcji, a następnie zwraca tę zmienną. Druga funkcja po prostu zwraca wartość bezpośrednio.
Czy Python zamienia je w równoważny kod bajtowy? Czy któryś z nich jest szybszy?
Przypadek 1 :
def func():
a = 42
return a
Przypadek 2 :
def func():
return 42
python
interpreter
python-internals
Jayesh
źródło
źródło
dis.dis(..)
obu, zobaczysz, że istnieje różnica , więc tak. Ale w większości rzeczywistych aplikacji narzut tego w porównaniu z opóźnieniem przetwarzania w funkcji nie jest tak duży.Odpowiedzi:
Nie, to nieprawda .
Kompilacja do kodu bajtowego CPythona jest przekazywana tylko przez mały optymalizator wizjera, który jest przeznaczony do wykonywania tylko podstawowych optymalizacji (patrz test_peepholer.py w zestawie testów, aby uzyskać więcej informacji na temat tych optymalizacji).
Aby zobaczyć, co naprawdę się wydarzy, użyj
dis
*, aby zobaczyć wygenerowane instrukcje. Dla pierwszej funkcji zawierającej przypisanie:Natomiast dla drugiej funkcji:
Dwie kolejne (szybkie) instrukcje są używane w pierwszej:
STORE_FAST
iLOAD_FAST
. Tworzą one szybkie zapisywanie i pobieranie wartości wfastlocals
tablicy bieżącej ramki wykonania. Następnie w obu przypadkachRETURN_VALUE
wykonywany jest a . Tak więc druga jest bardzo nieznaczna szybsza ze względu na mniej poleceń potrzebnych do wykonania.Ogólnie należy pamiętać, że kompilator CPython jest konserwatywny w optymalizacjach, które wykonuje. Nie jest i nie stara się być tak sprytny, jak inne kompilatory (które generalnie mają również znacznie więcej informacji do pracy). Głównym celem projektu, oprócz oczywistej poprawności, jest a) zachowanie prostoty i b) jak najszybsza kompilacja ich, aby nawet nie zauważyć, że istnieje faza kompilacji.
W końcu nie powinieneś martwić się drobnymi problemami, takimi jak ten. Korzyść w szybkości jest niewielka, stała i przyćmiona przez narzut wynikający z faktu, że Python jest interpretowany.
*
dis
to mały moduł Pythona, który dezasembluje Twój kod, możesz go użyć, aby zobaczyć kod bajtowy Pythona, który wykona maszyna wirtualna.Uwaga: jak stwierdzono również w komentarzu @Jorn Vernee, jest to specyficzne dla implementacji Pythona w CPythonie. Inne implementacje mogą wykonywać bardziej agresywne optymalizacje, jeśli sobie tego życzą, CPython nie.
źródło
Oba są zasadniczo takie same, z wyjątkiem tego, że w pierwszym przypadku obiekt
42
jest po prostu przypisany do zmiennej o nazwiea
lub, innymi słowy, nazwy (tj.a
) Odnoszą się do wartości (tj42
.). Z technicznego punktu widzenia nie wykonuje żadnego zadania, w tym sensie, że nigdy nie kopiuje żadnych danych.Podczas
return
ing to nazwane powiązaniea
jest zwracane w pierwszym przypadku, podczas gdy obiekt42
jest zwracany w drugim przypadku.Aby uzyskać więcej informacji, zapoznaj się z tym wspaniałym artykułem Neda Batcheldera
źródło