Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python Opcodes

Python Opcodes

Артём Апалько (RedMadRobot backend-dev) @ Moscow Python Meetup 45
"Обзорный доклад по опкодам в питоне. Изменения в Python 3.6 (изменение размера, оптимизация branch-prediction)".
Видео: http://www.moscowpython.ru/meetup/45/python-opcodes/

Moscow Python Meetup
PRO

May 25, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Opcodes и нововведения
    в
    Python 3.6
    Апалько Артём
    MoscowPython Meetup 45

    View Slide

  2. DISCLAIMER

    View Slide

  3. >>> def modulo(a, b):
    ... return a % b
    >>> modulo(6, 9)
    6
    3

    View Slide

  4. 4

    View Slide

  5. 1. Лексический анализ - исходный код в токены;
    2. Парсинг - токены в АСД;
    3. Компиляция - АСД в байткод;
    4. Интерпретация - исполняет байткод.
    5

    View Slide

  6. AST нашей функции
    6

    View Slide

  7. Объекты функций и
    объектные модули
    Объектный модуль файл с промежуточным представлением модуля программы в
    результате обработки исходного кода компилятором.
    >>> modulo.__code__
    ", line 1>
    >>> dir(modulo.__code__)
    ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
    '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
    '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename',
    'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name',
    'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
    7

    View Slide

  8. Байткод
    >>> modulo.__code__.co_varnames
    ('a', ‘b')
    >>> modulo.__code__.co_code
    b’|\x00|\x01\x16\x00S\x00’
    [format(b, 'b').zfill(8) for b in modulus.__code__.co_code]
    ['01111100', '00000000', '01111100', '00000001', '00010110', '00000000', '01010011',
    ‘00000000']
    >>> [int(b) for b in modulo.__code__.co_code ]
    [124, 0, 0, 124, 1, 0, 22, 83]
    8

    View Slide

  9. Используем dis
    >>> dis.dis(modulo)
    2 0 LOAD_FAST 0 (a)
    3 LOAD_FAST 1 (b)
    6 BINARY_MODULO
    7 RETURN_VALUE
    2 - номер строки в исходном коде
    0, 3, 6, 7 - смещение команд в байткоде
    LOAD_FAST, BINARY_MODYLO - название опкода
    0, 1 - позиция аргумента в пространстве имен
    9

    View Slide

  10. >>> modulo('6 %s', 9)
    '6 9'
    10

    View Slide

  11. 11

    View Slide

  12. ceval.c
    TARGET(BINARY_MODULO) {
    PyObject *divisor = POP();
    PyObject *dividend = TOP();
    PyObject *res;
    if (PyUnicode_CheckExact(dividend) && (
    !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) {
    // fast path; string formatting, but not if the RHS is a str subclass
    // (see issue28598)
    res = PyUnicode_Format(dividend, divisor);
    } else {
    res = PyNumber_Remainder(dividend, divisor);
    }
    Py_DECREF(divisor);
    Py_DECREF(dividend);
    SET_TOP(res);
    if (res == NULL)
    goto error;
    DISPATCH();
    } 12

    View Slide

  13. Итого
    • Опкод - инструкция интерпретатору (1 байт без
    аргументов и 3 байта с аргументами);
    • Интерпретатор CPython - цикл внутри которого
    switch по опкодам
    13

    View Slide

  14. Major new features of the 3.6
    series, compared to 3.5
    PEP 468, Preserving Keyword Argument Order
    PEP 487, Simpler customisation of class creation
    PEP 495, Local Time Disambiguation
    PEP 498, Literal String Formatting
    PEP 506, Adding A Secrets Module To The Standard Library
    PEP 509, Add a private version to dict
    PEP 515, Underscores in Numeric Literals
    PEP 519, Adding a file system path protocol
    PEP 520, Preserving Class Attribute Definition Order
    PEP 523, Adding a frame evaluation API to CPython
    PEP 524, Make os.urandom() blocking on Linux (during
    system startup)
    PEP 525, Asynchronous Generators (provisional)
    PEP 526, Syntax for Variable Annotations (provisional)
    PEP 528, Change Windows console encoding to UTF-8
    PEP 529, Change Windows filesystem encoding to UTF-8
    PEP 530, Asynchronous Comprehensions
    14

    View Slide

  15. Issue 26647
    Title: ceval, use Wordcode, 16-
    bit bytecode
    15

    View Slide

  16. Байткод 3.5 vs 3.6
    Python 3.5
    2 0 LOAD_FAST 0 (a)
    3 LOAD_FAST 1 (b)
    6 BINARY_MODULO
    7 RETURN_VALUE
    [124,0,0,124,1,0,22,83]
    Python 3.6
    2 0 LOAD_FAST 0 (a)
    2 LOAD_FAST 1 (b)
    4 BINARY_MODULO
    6 RETURN_VALUE
    [124,0,124,1,22,0,83,0]
    16

    View Slide

  17. • Не нужно считать на сколько сдвинуть указатель
    инструкции;
    • Экономия памяти для большинства случаев
    17

    View Slide

  18. Вместо тысячи слов
    - if (HAS_ARG(opcode))
    - oparg = NEXTARG();
    + oparg = NEXTARG();
    18

    View Slide

  19. Benchmarks
    Faster (27):
    - unpack_sequence: 1.11x faster
    - simple_logging: 1.11x faster
    - silent_logging: 1.10x faster
    - formatted_logging: 1.09x faster
    - raytrace: 1.08x faster
    - chaos: 1.08x faster
    - etree_process: 1.08x faster
    - call_simple: 1.07x faster
    - mako_v2: 1.07x faster
    - tornado_http: 1.07x faster
    - nqueens: 1.07x faster
    - regex_compile: 1.06x faster
    - pathlib: 1.06x faster
    - 2to3: 1.06x faster
    - richards: 1.05x faster
    - spectral_norm: 1.05x faster
    - etree_generate: 1.05x faster
    - chameleon_v2: 1.04x faster
    - pickle_list: 1.03x faster
    - pickle_dict: 1.03x faster
    - regex_v8: 1.03x faster
    - go: 1.03x faster
    - call_method: 1.03x faster
    - django_v3: 1.03x faster
    - telco: 1.02x faster
    - json_load: 1.02x faster
    - call_method_unknown: 1.02x faster
    Slower (1):
    - fannkuch: 1.07x slower
    Not significat (14):
    - unpickle_list
    - startup_nosite
    - regex_effbot
    - pidigits
    - normal_startup
    - nbody
    - meteor_contest
    - json_dump_v2
    - float
    - fastunpickle
    - fastpickle
    - etree_parse
    - etree_iterparse
    - call_method_slots
    19

    View Slide

  20. Итого
    • Скорость: +10%
    • Размер байткода: - 30%*
    20

    View Slide

  21. Вопросы?
    Апалько Артём
    telegram: hjortron
    mail: [email protected]
    Вакансии: http://www.redmadrobot.ru/vacancies/python-developer-2
    21

    View Slide