Upload
it-people
View
495
Download
3
Embed Size (px)
Citation preview
Оптимизация: на грани и за
Антон ПатрушевPyCon Russia, 19/09/2015
О себе
• Highload на Python и C++– Noda Interaction Platforms (ex-CTO)
• PyCon Russia• РКИК ООН– Python/Java/JavaScript
Disclaimer
• Этот доклад содержит опасные хаки• Не делайте так никогда• Если сделаете – не ссылайтесь на меня• В блоках кода не Python, а псевдокод• Всё что здесь написано - выдумка
Жалобы от мам, жён и тимлидов о том что вы вернулись с конференции «какой-то другой»
НЕ ПРИНИМАЮТСЯ
Признание
• Мы так дела(ем|ли)• Нам сначала было немножко больно• Потом стало хорошо
О докладе
• Про GC– Коротко о сборке мусора– Когда GC это боль?– Жизнь без GC: есть ли она?
• {Про AST, Про байткод}– Intro– Разоблачение
Сборка мусора
• Счётчик ссылок– Часть объекта– Увеличиваем/уменьшаем– Если равен нулю удаляем (или gc.garbage)– Каскадно уменьшаем счётчики
• GC– Ищем изолированные циклы– Cносим их целиком
Real-time
• Мягкий– «лучше бы не опаздывать»– Подходит когда «на той стороне» человек
• Жёсткий– Опоздание == DOS– Больше относится к взаимодействию между
компонентами систем
GC
• Когда запустится – не известно– Gen(0)=>(allocates – deallocates)– Gen(x)=>num(Gen(x-1))
• Сколько будет длиться – не известно– Зависит от количества объектов
All your CPUs are belongs to GC
Есть ли жизнь без GC? Финализируйте объекты явно
Explicit is better than implicit Следите за памятью
gc.get_count()[0] Ловите циклы
gc.set_debug(gc.DEBUG_SAVEALL) gc.collect(0) gc.garbage
Есть ли жизнь без GC? Сделайте бэкдор в своё приложение (!!!)
twisted.manhole rfoo.utils.rconsole pydevd (теоретически) возможно подключиться GDB
Включите в установку objgraph
Цикл
Цикл
Цикл: решение
• Явная финализация– Room.close()– Client.leave(room)
Поиск циклов
Неожиданные циклы
Неожиданные циклы: Closure
Неожиданные циклы
Если явно не выходит
• weakref
Опасный трюк с id
Objgraph ваш друг
• find_{ref,backref}_chain• show_growth• show_most_common_types
С такими друзьями врагов не надо
Повышаем градус безумия
Logging: mission impossible
• Вычисление аргументов• Вызов и передача параметров• «Паразитная» информация при
профилировании• Касается многих языков
Logging: как быть?
• Переписать весь код так
• Читаемость?• Накладные расходы?• Большая база кода?
А что если…
• Каким-то образом на старте программы взять и вырезать ненужные уровни логирования?
Abstract Syntax Tree
• Машиночитаемое представление исходного кода
• Дерево• Source=>AST=>bytecode• Преобразования необратимы• AST->AST->AST->….– visitor
Logging: AST-transformation
• Possibly impossible is possible• Import hook• Полное вырезание отключенных уровней• Ограничения– Все вызовы должны выглядеть одинаково– LogLevel нельзя будет сменить без рестарта
Ещё разок про плюсы
• Плюсы это такой язык программирования• Вызов логирования исчезает полностью• Не надо править код• Профилирование• «Дополнительная» производительность в
«экстремальных» режимах работы
Let’s get deeper
bytecode
• Следующее преобразование– AST=>bytecode
• Язык CPython VM• Батарейки– Dis– byteplay
LOAD_CONST vs LOAD_GLOBAL
• Dict vs List[x]
Bytecode-transformation
• Общий принцип– Ищем в co_code LOAD_GLOBAL– Добавляем её аргумент в co_consts– Меняем инструкцию на LOAD_CONST
• Import hook– Глобальные оптимизации
• Decorator– Локализация изменений
Bytecode: результаты
• Абослютного значения нет• Для такого кода
• Время выполнения меньше на 12-15%
Bytecode/AST
• Производительность без изменения кода• «Отключаемые» улучшения
Здесь должны быть ссылки
• http://compilers.pydata.org/• https://github.com/apatrushev/bycot
Это всё.
Вопросы[email protected]