dis
ist nützlich, zum Beispiel, wenn Sie unterschiedlichen Code haben, der dasselbe tut, und Sie sich fragen, wo der Leistungsunterschied liegt.
Beispiel: list += [item]
vs list.append(item)
def f(x): return 2*x
def f1(func, nums):
result = []
for item in nums:
result += [fun(item)]
return result
def f2(func, nums):
result = []
for item in nums:
result.append(fun(item))
return result
timeit.timeit
sagt, dass f2(f, range(100))
ungefähr doppelt so schnell ist wie f1(f, range(100)
. Warum?
(Interessanterweise ist f2
ungefähr so schnell wie map(f, range(100))
ist.)
f1
Sie können den gesamten Output von dis sehen, indem Sie dis.dis(f1)
aufrufen, hier ist Zeile 4.
4 19 LOAD_FAST 2 (result)
22 LOAD_FAST 1 (fun)
25 LOAD_FAST 3 (item)
28 CALL_FUNCTION 1
31 BUILD_LIST 1
34 INPLACE_ADD
35 STORE_FAST 2 (result)
38 JUMP_ABSOLUTE 13
>> 41 POP_BLOCK
f2
Auch hier ist nur Zeile 4:
4 19 LOAD_FAST 2 (result)
22 LOAD_ATTR 0 (append)
25 LOAD_FAST 1 (fun)
28 LOAD_FAST 3 (item)
31 CALL_FUNCTION 1
34 CALL_FUNCTION 1
37 POP_TOP
38 JUMP_ABSOLUTE 13
>> 41 POP_BLOCK
Unterschied erkennen
In f1
müssen wir:
fun
auf item
aufrufen (Opcode 28)
- Daraus eine Liste machen (Opcode 31, teuer!)
- Es zu
result
hinzufügen (Opcode 34)
- Den zurückgegebenen Wert in
result
speichern (Opcode 35)
In f2
hingegen machen wir einfach:
fun
auf item
aufrufen (Opcode 31)
append
auf result
aufrufen (Opcode 34; C-Code: schnell!)
Dies erklärt, warum die (mMn) ausdrucksstärkere list += [value]
Methode viel langsamer ist als die list.append()
Methode.
Abgesehen davon ist dis.dis
hauptsächlich nützlich aus Neugierde und um zu versuchen, Code aus .pyc
Dateien nachzuvollziehen, für die Sie keine Quelle haben, ohne ein Vermögen auszugeben :)