Wpis z mikrobloga

Decorator for BindingConstants at compile time
Wow, optymizacja bytecodu pythona w locie. Kawał świetnego kodu i jaka inspiracja (przynajmnjiej dla mnie).

Poprawcie mnie jeśli źle myślę. Dostęp do obiektów w globalnej przestrzeni nazw jest relatywnie wolny w porównaniu do zmiennych lokalnych (heap vs stack speed ble, ble ble) dlatego w powyższym linku np dekorator przeszukuje bytekod fumkcji w poszukiwaniu opcodu LOADGLOBAL i zamienia go na LOADCONST. Emarajt?

np jeśli zdefiniujemy sobie coś takiego:

>>>a = "foo"'
'>>>def bar():

'b = a'
'c = 1'
'return c'

możemy podejrzeć bytekod powyższej funkcji w bardzo prosty sposób (Python3):
'>>>bar._code.cocode'
'b"t\x00\x00}\x00\x00d\x01\x00}\x01\x00|\x01\x00S"'
trochę bardziej czytelnie:
'>>>list(bar._code.cocode)'
'[116, 0, 0, 125, 0, 0, 100, 1, 0, 125, 1, 0, 124, 1, 0, 83]'
Wartość 116 to wartośść opcodu LOADGLOBALS, dwa nastepne elementy to w uproszczeniu argumenty danego opcodu.
Oczywiście nie jesteśmy Neo aby swobodnie czytać to na surowo. Biblioteka standardowa ma moduł
dis, który wyrzuca bardziej przyjazny wynik:
'>>>import dis'
'>>>dis.dis(bar)'
' 2 0 LOAD
GLOBAL 0 (a)
3 STOREFAST 0 (b) '
''
' 3 6 LOAD
CONST 1 (1) '
' 9 STOREFAST 1 (c) '
''
' 4 12 LOAD
FAST 1 (c) '
' 15 RETURNVALUE '

Moglibyśmy spróbować ręcznie zmodyfikować opkod na LOAD
CONST ale wymagałoby to jeszcze zmiany kilku innych atrybutów oraz ponownego zdefiniowania dekorowanej funkcji używając "type". Zagadnienie porusza sporo ciekawych tematów, to za dużo jak na wpis na mirko.

Wersja powyzszego dekoratora dla Pythona 3
Moduł dis python 3
#python #programowanie
  • 4
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@Ginden: Ciekawy artykuł, zastosowanie biblioteki stworzonej przez autora wydaje się jednak ograniczać do obliczeń numerycznych. Będę musiał jeszcze przegryźć się przez tekst zanim lepiej zrozumiem co tam jest napisane. Widzę, że na końcu jest też odnośnik do strony którą zalinkowałem we wpisie :) Dzięki!
  • Odpowiedz