3 Stimmen

In welchem Szenario ist es nützlich, Disassembly in Python zu verwenden?

Das dis-Modul kann effektiv verwendet werden, um Python-Methoden, Funktionen und Klassen in niederstufige Interpreter-Anweisungen zu zerlegen.

Ich weiß, dass dis-Informationen für folgendes verwendet werden können:
1. Rennbedingungen in Programmen mit Threads finden
2. Mögliche Optimierungen finden

Hast du aus deiner Erfahrung heraus noch andere Szenarien, in denen das Zerlegen von Python mittels Disassembly nützlich sein könnte?

7voto

badp Punkte 11166

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 :)

5voto

Alex Martelli Punkte 805329

Ich betrachte das dis Modul im Grunde als ein Lernwerkzeug. Zu verstehen, welche Opcodes ein bestimmter Ausschnitt von Python-Code generiert, ist ein Anfang, um mehr "Tiefe" in Ihr Verständnis von Python zu bekommen - die "abstrakte" Verständnis seiner Semantik in eine (etwas mehr) konkrete Implementierung zu verwurzeln. Manchmal kann der genaue Grund, warum ein bestimmter Python-Ausschnitt sich so verhält, wie er es tut, schwer "von oben nach unten" nur durch reines logisches Denken aus den "Regeln" der Python-Semantik zu erfassen sein: In solchen Fällen kann die Verstärkung des Studiums mit einer "von unten nach oben" Überprüfung (basierend auf einer möglichen Implementierung, natürlich - andere Implementierungen wären auch möglich;-) wirklich dazu beitragen, die Effektivität des Studiums zu verbessern.

3voto

Jason Baker Punkte 180981

Für den täglichen Python-Programmier-Alltag nicht viel. Es ist jedoch nützlich, wenn Sie herausfinden möchten, warum etwas auf eine Weise schneller ist als auf eine andere. Manchmal habe ich es auch verwendet, um genau herauszufinden, wie der Interpreter einige obskure Code-Stücke behandelt. Aber um ehrlich zu sein, finde ich nur sehr selten eine praktische Anwendung dafür.

Andererseits, wenn Ihr Ziel darin besteht, Python zu verstehen und nicht nur in der Lage zu sein, darin zu programmieren, dann ist es ein unschätzbares Werkzeug. Haben Sie sich jemals gefragt, wie eine Funktionsdefinition funktioniert? Hier haben Sie es:

>>> def f():
...     def foo(x=[1, 2, 3]):
...         y = [4,]
...         return x + y
... 
>>> dis(f)
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 LOAD_CONST               4 (", line 2>)
             15 MAKE_FUNCTION            1
             18 STORE_FAST               0 (foo)
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        

`

Sie können sehen, dass dies geschieht, indem die Konstanten 1, 2 und 3 auf den Stapel geschoben werden, der Inhalt des Stapels in eine Liste eingefügt wird, dies in einen Code-Objekt geladen wird, die Code-Funktion in ein Objekt umgewandelt wird und es in eine Variable namens foo gespeichert wird.

`

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X