• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Встраивание Python в мобильные приложения – нюансы interoperation, новые подходы к разработке.  Никита Лесников -
 

Встраивание Python в мобильные приложения – нюансы interoperation, новые подходы к разработке. Никита Лесников -

on

  • 959 views

 

Statistics

Views

Total Views
959
Views on SlideShare
906
Embed Views
53

Actions

Likes
0
Downloads
4
Comments
0

2 Embeds 53

http://dev.by 52
http://www.dev.by 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Встраивание Python в мобильные приложения – нюансы interoperation, новые подходы к разработке.  Никита Лесников - Встраивание Python в мобильные приложения – нюансы interoperation, новые подходы к разработке. Никита Лесников - Presentation Transcript

    • Встраивание Python в мобильные приложениянюансы interoperation, новые приемы разработки Никита Лесников
    • Дисклеймер Доклад носит общий характер, без нюансов отдельных платформ
    • Дисклеймер Доклад носит общий характер, без нюансов отдельных платформ Все описанные решения не “коробочные”, чтобы велосипед поехал, надо существенно поработать напильником
    • Дисклеймер Доклад носит общий характер, без нюансов отдельных платформ Все описанные решения не “коробочные”, чтобы велосипед поехал, надо существенно поработать напильником В простых случаях, где нет многоплатформенности или серверной части, многие описанные решения будут оверкилльны
    • Дисклеймер Доклад носит общий характер, без нюансов отдельных платформ Все описанные решения не “коробочные”, чтобы велосипед поехал, надо существенно поработать напильником В простых случаях, где нет многоплатформенности или серверной части, многие описанные решения будут оверкилльны Не смущает вышесказанное? Тогда поехали...
    • Зоопарк ЯП Языки программирования не являются “вещью в себе”
    • Зоопарк ЯП Языки программирования не являются “вещью в себе” Часто область применения определяет больше, нежели синтаксис или дисциплина типизации
    • Зоопарк ЯП Языки программирования не являются “вещью в себе” Часто область применения определяет больше, нежели синтаксис или дисциплина типизации В отдельных областях de facto сложились решения, от которых отойти нельзя при всех кажущихся недостатках
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение?
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать:
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц 2. CSS - стилизация страниц
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц 2. CSS - стилизация страниц 3. JavaScript - клиентское скриптование
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц 2. CSS - стилизация страниц 3. JavaScript - клиентское скриптование 4. Что угодно еще - серверная часть
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц 2. CSS - стилизация страниц 3. JavaScript - клиентское скриптование 4. Что угодно еще - серверная часть Четыре языка для описания одной сущности!
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц 2. CSS - стилизация страниц 3. JavaScript - клиентское скриптование 4. Что угодно еще - серверная часть Четыре языка для описания одной сущности! Организационный кошмар
    • Web - классический пример Сколько языков необходимо, чтобы создать типичное веб-приложение? Попробуем посчитать: 1. HTML - разметка страниц 2. CSS - стилизация страниц 3. JavaScript - клиентское скриптование 4. Что угодно еще - серверная часть Четыре языка для описания одной сущности! Организационный кошмар Повторное использование кода невозможно
    • Web - попытки решить проблему node.js - возможность разработки серверной логики на JavaScript (позволяет code reuse между клиентской и серверной частями)
    • Web - попытки решить проблему node.js - возможность разработки серверной логики на JavaScript (позволяет code reuse между клиентской и серверной частями) шаблонизаторы - отделяют HTML-код страницы от ее логического представления, делая возможным смену представления без правки бизнес-логики
    • Web - попытки решить проблему node.js - возможность разработки серверной логики на JavaScript (позволяет code reuse между клиентской и серверной частями) шаблонизаторы - отделяют HTML-код страницы от ее логического представления, делая возможным смену представления без правки бизнес-логики Объективные качества упомянутых подходов лежат за рамками этого доклада
    • Мобильная разработка чем-то похожа... Авторы кроссплатформенных приложений для мобильных платформ сталкиваются с (почти той же) проблемой
    • Мобильная разработка чем-то похожа... Авторы кроссплатформенных приложений для мобильных платформ сталкиваются с (почти той же) проблемой Разве что код надо переписывать один и тот же на разных языках, а не компоновать единый проект из разнородных кусочков
    • Мобильная разработка чем-то похожа... Авторы кроссплатформенных приложений для мобильных платформ сталкиваются с (почти той же) проблемой Разве что код надо переписывать один и тот же на разных языках, а не компоновать единый проект из разнородных кусочков Java, Objective-C и C++ достаточно различны, чтобы сделать автоматическое портирование достаточно нетривиальным
    • Мобильная разработка чем-то похожа... Авторы кроссплатформенных приложений для мобильных платформ сталкиваются с (почти той же) проблемой Разве что код надо переписывать один и тот же на разных языках, а не компоновать единый проект из разнородных кусочков Java, Objective-C и C++ достаточно различны, чтобы сделать автоматическое портирование достаточно нетривиальным Даже поддержка native code многого не гарантирует - Objective-C++ не совместим на уровне лексера с C++03, на Android non-POSIX-compliant-libc
    • Мобильная разработка чем-то похожа... Авторы кроссплатформенных приложений для мобильных платформ сталкиваются с (почти той же) проблемой Разве что код надо переписывать один и тот же на разных языках, а не компоновать единый проект из разнородных кусочков Java, Objective-C и C++ достаточно различны, чтобы сделать автоматическое портирование достаточно нетривиальным Даже поддержка native code многого не гарантирует - Objective-C++ не совместим на уровне лексера с C++03, на Android non-POSIX-compliant-libc Если у проекта есть серверная часть, добавляются “языковые проблемы веба”
    • ...однако и чем-то различна У всех платформ современных смартфонов, за исключением Windows Phone 7, есть-таки общая черта
    • ...однако и чем-то различна У всех платформ современных смартфонов, за исключением Windows Phone 7, есть-таки общая черта Как ни странно, это ANSI C
    • ...однако и чем-то различна У всех платформ современных смартфонов, за исключением Windows Phone 7, есть-таки общая черта Как ни странно, это ANSI C Objective-C является его прямым надмножеством, у Android с C изначально все хорошо
    • ...однако и чем-то различна У всех платформ современных смартфонов, за исключением Windows Phone 7, есть-таки общая черта Как ни странно, это ANSI C Objective-C является его прямым надмножеством, у Android с C изначально все хорошо Разве что как язык C не слишком воодушевляющ - подсчет битов является последним делом, которым хочется заниматься в большом кроссплатформенном проекте с и так ограниченными ресурсами
    • ...однако и чем-то различна У всех платформ современных смартфонов, за исключением Windows Phone 7, есть-таки общая черта Как ни странно, это ANSI C Objective-C является его прямым надмножеством, у Android с C изначально все хорошо Разве что как язык C не слишком воодушевляющ - подсчет битов является последним делом, которым хочется заниматься в большом кроссплатформенном проекте с и так ограниченными ресурсами Особенно, когда “высвободившаяся” производительность изначально не нужна
    • Казалось бы, причем тут Python? Python - интерпретируемый высокоуровневый язык с динамической типизацией
    • Казалось бы, причем тут Python? Python - интерпретируемый высокоуровневый язык с динамической типизацией ООП, интроспекция, метапрограммирование - все в наличии
    • Казалось бы, причем тут Python? Python - интерпретируемый высокоуровневый язык с динамической типизацией ООП, интроспекция, метапрограммирование - все в наличии Куча крутых библиотек, в том числе в базовой поставке (что отражено в девизе - batteries included)
    • Казалось бы, причем тут Python? Python - интерпретируемый высокоуровневый язык с динамической типизацией ООП, интроспекция, метапрограммирование - все в наличии Куча крутых библиотек, в том числе в базовой поставке (что отражено в девизе - batteries included) Простой API для C, что автоматически означает простой API для чего угодно
    • Казалось бы, причем тут Python? Python - интерпретируемый высокоуровневый язык с динамической типизацией ООП, интроспекция, метапрограммирование - все в наличии Куча крутых библиотек, в том числе в базовой поставке (что отражено в девизе - batteries included) Простой API для C, что автоматически означает простой API для чего угодно Весь рантайм также написан на С и представляет из себя самодостаточную систему для разработки, отладки и выполнения кода
    • Казалось бы, причем тут Python? Python - интерпретируемый высокоуровневый язык с динамической типизацией ООП, интроспекция, метапрограммирование - все в наличии Куча крутых библиотек, в том числе в базовой поставке (что отражено в девизе - batteries included) Простой API для C, что автоматически означает простой API для чего угодно Весь рантайм также написан на С и представляет из себя самодостаточную систему для разработки, отладки и выполнения кода Этот самый “весь рантайм” можно сделать частью вашего приложения
    • Как это можно использовать? Писать на Python большую часть слабокритичного к платформенным нюансам и производительности кода
    • Как это можно использовать? Писать на Python большую часть слабокритичного к платформенным нюансам и производительности кода Как следствие, нативная и/или платформозависимая часть сократится
    • Как это можно использовать? Писать на Python большую часть слабокритичного к платформенным нюансам и производительности кода Как следствие, нативная и/или платформозависимая часть сократится Общее количество кода станет сильно меньше, что всегда хорошо
    • Как это можно использовать? Писать на Python большую часть слабокритичного к платформенным нюансам и производительности кода Как следствие, нативная и/или платформозависимая часть сократится Общее количество кода станет сильно меньше, что всегда хорошо При адекватном подходе производительность будет более чем приемлимой
    • Почему именно Python? Больше вопрос вкуса
    • Почему именно Python? Больше вопрос вкуса Хорошая альтернатива - Lua, легче встраивается, но и стандартная библитека поменьше (“из коробки” ее фактически нет)
    • Почему именно Python? Больше вопрос вкуса Хорошая альтернатива - Lua, легче встраивается, но и стандартная библитека поменьше (“из коробки” ее фактически нет) Python очень консистентен и предсказуем - “неожиданностей” не бывает почти никогда при должном понимании основных концепций
    • Почему именно Python? Больше вопрос вкуса Хорошая альтернатива - Lua, легче встраивается, но и стандартная библитека поменьше (“из коробки” ее фактически нет) Python очень консистентен и предсказуем - “неожиданностей” не бывает почти никогда при должном понимании основных концепций “Должное понимание” - не некое абстрактное понятие, как, например, мифическое “хорошее знание C++”, оно вполне достижимо за очень ограниченный срок
    • Почему именно Python? Больше вопрос вкуса Хорошая альтернатива - Lua, легче встраивается, но и стандартная библитека поменьше (“из коробки” ее фактически нет) Python очень консистентен и предсказуем - “неожиданностей” не бывает почти никогда при должном понимании основных концепций “Должное понимание” - не некое абстрактное понятие, как, например, мифическое “хорошее знание C++”, оно вполне достижимо за очень ограниченный срок По опыту wargaming.net, программисты без прежнего знания Python, но с сильным бэкграундом в других областях, осваиваются за считанные дни
    • О чем я расскажу Цель - не перечислить написать reference manual по embedding API, а показать одно из возможных решений целого спектра проблем
    • О чем я расскажу Цель - не перечислить написать reference manual по embedding API, а показать одно из возможных решений целого спектра проблем Не знаете Python? Это не страшно, его знание тут некритично - повествование больше на уровне идей
    • О чем я расскажу Цель - не перечислить написать reference manual по embedding API, а показать одно из возможных решений целого спектра проблем Не знаете Python? Это не страшно, его знание тут некритично - повествование больше на уровне идей Мне тоже по ходу можно (и нужно) задавать вопросы, если что-то непонятно
    • Собственно по теме доклада :) Берем source distribution c исходниками Python
    • Собственно по теме доклада :) Берем source distribution c исходниками Python Собираем статическую библиотеку, отключив все ненужное
    • Собственно по теме доклада :) Берем source distribution c исходниками Python Собираем статическую библиотеку, отключив все ненужное “Все ненужное” - это почти все. И чем более почти, тем безболезненнее проходит сборка - core python собирается при помощи autotools и компилятора C, без внешних зависимостей вообще
    • Собственно по теме доклада :) Берем source distribution c исходниками Python Собираем статическую библиотеку, отключив все ненужное “Все ненужное” - это почти все. И чем более почти, тем безболезненнее проходит сборка - core python собирается при помощи autotools и компилятора C, без внешних зависимостей вообще Проблемы могут быть, но все решается быстрым поиском по core development документации, stackoverflow и подобным ресурсам
    • Собственно по теме доклада :) Берем source distribution c исходниками Python Собираем статическую библиотеку, отключив все ненужное “Все ненужное” - это почти все. И чем более почти, тем безболезненнее проходит сборка - core python собирается при помощи autotools и компилятора C, без внешних зависимостей вообще Проблемы могут быть, но все решается быстрым поиском по core development документации, stackoverflow и подобным ресурсам Большинство проблем лечатся ключами к configure
    • Собственно по теме доклада :) Берем source distribution c исходниками Python Собираем статическую библиотеку, отключив все ненужное “Все ненужное” - это почти все. И чем более почти, тем безболезненнее проходит сборка - core python собирается при помощи autotools и компилятора C, без внешних зависимостей вообще Проблемы могут быть, но все решается быстрым поиском по core development документации, stackoverflow и подобным ресурсам Большинство проблем лечатся ключами к configure Даже core сборка содержит много крутых вещей (коллекции, регэкспы, хеши, даты, сериализацию, адекватный Unicode)
    • Собственно по теме доклада :) Берем source distribution c исходниками Python Собираем статическую библиотеку, отключив все ненужное “Все ненужное” - это почти все. И чем более почти, тем безболезненнее проходит сборка - core python собирается при помощи autotools и компилятора C, без внешних зависимостей вообще Проблемы могут быть, но все решается быстрым поиском по core development документации, stackoverflow и подобным ресурсам Большинство проблем лечатся ключами к configure Даже core сборка содержит много крутых вещей (коллекции, регэкспы, хеши, даты, сериализацию, адекватный Unicode) Это всегда допустимый fallback
    • libPython.a есть? идем дальше Настраиваем линковку с этим блобом
    • libPython.a есть? идем дальше Настраиваем линковку с этим блобом Делаем вот так: #include <Python . h> void execute_python_code ( ) { Py_Initialize (); PyRun_SimpleString ( "python_code_here" ) ; Py_Finalize ( ) ; }
    • libPython.a есть? идем дальше Настраиваем линковку с этим блобом Делаем вот так: #include <Python . h> void execute_python_code ( ) { Py_Initialize (); PyRun_SimpleString ( "python_code_here" ) ; Py_Finalize ( ) ; } Все, мы исполнили код на Python
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант Годится, например, для Python-консоли времени выполнения
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант Годится, например, для Python-консоли времени выполнения Есть более тонкие инструменты
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант Годится, например, для Python-консоли времени выполнения Есть более тонкие инструменты Но суть та же:
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант Годится, например, для Python-консоли времени выполнения Есть более тонкие инструменты Но суть та же: 1. Если в другом потоке, лочим мутекс стейта
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант Годится, например, для Python-консоли времени выполнения Есть более тонкие инструменты Но суть та же: 1. Если в другом потоке, лочим мутекс стейта 2. Манипулируем состоянием, вызываем методы
    • Как-то слишком просто? Ну, это самый “высокоуровневый” вариант Годится, например, для Python-консоли времени выполнения Есть более тонкие инструменты Но суть та же: 1. Если в другом потоке, лочим мутекс стейта 2. Манипулируем состоянием, вызываем методы 3. Концептуально, все вызовы “в один конец” - из C в Python
    • А в обратную сторону как? Core python может не осилить реализацию многих компонент приложения, ибо там особые интерфейсы, имеющиеся в нативном коде, но “прозрачно” недоступные
    • А в обратную сторону как? Core python может не осилить реализацию многих компонент приложения, ибо там особые интерфейсы, имеющиеся в нативном коде, но “прозрачно” недоступные Плохо, писать много “скучного” кода на Python - наша цель
    • А в обратную сторону как? Core python может не осилить реализацию многих компонент приложения, ибо там особые интерфейсы, имеющиеся в нативном коде, но “прозрачно” недоступные Плохо, писать много “скучного” кода на Python - наша цель Да и спускать критичные по скорости ботлнеки в C/C++ тоже хотелось бы для спокойствия
    • А в обратную сторону как? Core python может не осилить реализацию многих компонент приложения, ибо там особые интерфейсы, имеющиеся в нативном коде, но “прозрачно” недоступные Плохо, писать много “скучного” кода на Python - наша цель Да и спускать критичные по скорости ботлнеки в C/C++ тоже хотелось бы для спокойствия Это решается написанием модулей расширения
    • Некоторые детали Придумываем для каждой сущности аналог в рантайме Python
    • Некоторые детали Придумываем для каждой сущности аналог в рантайме Python Пишем унылые функции-передергивалки, которые возьмут на себя bookkeeping референс-каунтинга, маршаллинга объектов Python в С и обратно
    • Некоторые детали Придумываем для каждой сущности аналог в рантайме Python Пишем унылые функции-передергивалки, которые возьмут на себя bookkeeping референс-каунтинга, маршаллинга объектов Python в С и обратно Заполняем сишную структуру, которая задаст интерпретатору интерфейс модуля
    • Некоторые детали Придумываем для каждой сущности аналог в рантайме Python Пишем унылые функции-передергивалки, которые возьмут на себя bookkeeping референс-каунтинга, маршаллинга объектов Python в С и обратно Заполняем сишную структуру, которая задаст интерпретатору интерфейс модуля Вызовем функцию-инициализатор модуля после старта интерпретатора
    • Некоторые детали Придумываем для каждой сущности аналог в рантайме Python Пишем унылые функции-передергивалки, которые возьмут на себя bookkeeping референс-каунтинга, маршаллинга объектов Python в С и обратно Заполняем сишную структуру, которая задаст интерпретатору интерфейс модуля Вызовем функцию-инициализатор модуля после старта интерпретатора Все, можно вызывать нативные функции из кода на Python.
    • Некоторые детали Придумываем для каждой сущности аналог в рантайме Python Пишем унылые функции-передергивалки, которые возьмут на себя bookkeeping референс-каунтинга, маршаллинга объектов Python в С и обратно Заполняем сишную структуру, которая задаст интерпретатору интерфейс модуля Вызовем функцию-инициализатор модуля после старта интерпретатора Все, можно вызывать нативные функции из кода на Python. В детали не буду вдаваться из-за регламента, но поверьте, там все дуболомно просто, разве что очень много бойлерплейта
    • Сторонние модули То же самое касается чужих модулей, распространяемых в исходниках
    • Сторонние модули То же самое касается чужих модулей, распространяемых в исходниках Во “взрослых” применениях они обычно собираются в shared library (.dll, .so, .dylib), однако никто не мешает слинковаться с ними статически и вызвать функцию-инициализатор вручную
    • Сторонние модули То же самое касается чужих модулей, распространяемых в исходниках Во “взрослых” применениях они обычно собираются в shared library (.dll, .so, .dylib), однако никто не мешает слинковаться с ними статически и вызвать функцию-инициализатор вручную Не стоит стесняться так делать
    • Сторонние модули То же самое касается чужих модулей, распространяемых в исходниках Во “взрослых” применениях они обычно собираются в shared library (.dll, .so, .dylib), однако никто не мешает слинковаться с ними статически и вызвать функцию-инициализатор вручную Не стоит стесняться так делать Идеальная на мой взгляд ситуация - когда код сразу вызывает питоновский аналог main, и лишь самые низкоуровневые вызовы приходят обратно на нативный уровень
    • Сторонние модули То же самое касается чужих модулей, распространяемых в исходниках Во “взрослых” применениях они обычно собираются в shared library (.dll, .so, .dylib), однако никто не мешает слинковаться с ними статически и вызвать функцию-инициализатор вручную Не стоит стесняться так делать Идеальная на мой взгляд ситуация - когда код сразу вызывает питоновский аналог main, и лишь самые низкоуровневые вызовы приходят обратно на нативный уровень Нативный уровень уменьшается по максимуму, и портировать его намного проще (код на Python ведь переписывать не нужно)
    • GameDev - чуть ли не идеальный случай Интерфейсов мало - OpenGL, OpenAL, тач, несколько дополнительных ивентов
    • GameDev - чуть ли не идеальный случай Интерфейсов мало - OpenGL, OpenAL, тач, несколько дополнительных ивентов Хранилище ресурсов, сеть, UI - можно часто шарить, ведь они все равно “свои”
    • GameDev - чуть ли не идеальный случай Интерфейсов мало - OpenGL, OpenAL, тач, несколько дополнительных ивентов Хранилище ресурсов, сеть, UI - можно часто шарить, ведь они все равно “свои” Тяжелые вещи вроде AI и поиска путей спускаются в нативные модули
    • SWIG - пишем обвязку проще SWIG - генератор связующего кода по слегка размеченному “файлу интерфейса” для кода на C/C++.
    • SWIG - пишем обвязку проще SWIG - генератор связующего кода по слегка размеченному “файлу интерфейса” для кода на C/C++. Фактически способен по .h файлу сгенерировать для сишных функций полный аналог, с адекватным сопоставлением типов (вроде превращения int* в список чисел)
    • SWIG - пишем обвязку проще SWIG - генератор связующего кода по слегка размеченному “файлу интерфейса” для кода на C/C++. Фактически способен по .h файлу сгенерировать для сишных функций полный аналог, с адекватным сопоставлением типов (вроде превращения int* в список чисел) С memory policy тоже все хорошо - сишные объекты наследуют поведение reference counted объектов Python.
    • SWIG - пишем обвязку проще SWIG - генератор связующего кода по слегка размеченному “файлу интерфейса” для кода на C/C++. Фактически способен по .h файлу сгенерировать для сишных функций полный аналог, с адекватным сопоставлением типов (вроде превращения int* в список чисел) С memory policy тоже все хорошо - сишные объекты наследуют поведение reference counted объектов Python. Умеет “зеркалировать” и иерархии классов C++
    • SWIG - пишем обвязку проще SWIG - генератор связующего кода по слегка размеченному “файлу интерфейса” для кода на C/C++. Фактически способен по .h файлу сгенерировать для сишных функций полный аналог, с адекватным сопоставлением типов (вроде превращения int* в список чисел) С memory policy тоже все хорошо - сишные объекты наследуют поведение reference counted объектов Python. Умеет “зеркалировать” и иерархии классов C++ Радикально снимает вопрос написания кода взаимодействия Python-C
    • SWIG - пример example.i %module native_code %{ i n t * heavy_func ( char* p ) ; %} example.py import native_code s = sum( native_code . heavy_func ( " test " ) )
    • boost::python Темплейтная библиотека для C++, добивающаяся аналогичных целей
    • boost::python Темплейтная библиотека для C++, добивающаяся аналогичных целей По целям аналогична SWIG, но достигает их другим способом
    • boost::python Темплейтная библиотека для C++, добивающаяся аналогичных целей По целям аналогична SWIG, но достигает их другим способом Может быть удобнее, когда зависимость от boost не пугает, а усложнение процесса сборки еще одной утилитой (SWIG) нежелательно
    • boost::python Темплейтная библиотека для C++, добивающаяся аналогичных целей По целям аналогична SWIG, но достигает их другим способом Может быть удобнее, когда зависимость от boost не пугает, а усложнение процесса сборки еще одной утилитой (SWIG) нежелательно Интерфейсы задаются макросами препроцессора в коде
    • boost::python Темплейтная библиотека для C++, добивающаяся аналогичных целей По целям аналогична SWIG, но достигает их другим способом Может быть удобнее, когда зависимость от boost не пугает, а усложнение процесса сборки еще одной утилитой (SWIG) нежелательно Интерфейсы задаются макросами препроцессора в коде В отличие от SWIG позволяет пользоваться функциями embedding API напрямую, что может быть важно (SWIG, впрочем, не запрещает тоже, однако править сгенерированный код методологически неправильно)
    • Производительность Зная способы размещения кода как в нативной, так и в скриптовой части приложения, надо уметь прикидывать, какую подсистему куда отнести
    • Производительность Зная способы размещения кода как в нативной, так и в скриптовой части приложения, надо уметь прикидывать, какую подсистему куда отнести Следует представлять себе запросы скриптов к памяти и процессорному времени
    • Производительность Зная способы размещения кода как в нативной, так и в скриптовой части приложения, надо уметь прикидывать, какую подсистему куда отнести Следует представлять себе запросы скриптов к памяти и процессорному времени Там все очень плохо
    • "Все плохо"-1, память В зависимости от разрядности интерпретатора и наличия отладочных опций при сборке размер объекта Python может сильно плавать, но все равно не может быть меньше двух указателей
    • "Все плохо"-1, память В зависимости от разрядности интерпретатора и наличия отладочных опций при сборке размер объекта Python может сильно плавать, но все равно не может быть меньше двух указателей В Python все - объект
    • "Все плохо"-1, память В зависимости от разрядности интерпретатора и наличия отладочных опций при сборке размер объекта Python может сильно плавать, но все равно не может быть меньше двух указателей В Python все - объект int размером 30 байт - это нормально
    • "Все плохо"-1, память В зависимости от разрядности интерпретатора и наличия отладочных опций при сборке размер объекта Python может сильно плавать, но все равно не может быть меньше двух указателей В Python все - объект int размером 30 байт - это нормально Инстансы классов (насколько это понятие применимо к Python) - часто от 300 байт
    • "Все плохо"-2, скорость Динамическая типизация - проверка типов на каждой операции
    • "Все плохо"-2, скорость Динамическая типизация - проверка типов на каждой операции Reference counting - постоянные cache misses из-за нелокального обращения к памяти
    • "Все плохо"-2, скорость Динамическая типизация - проверка типов на каждой операции Reference counting - постоянные cache misses из-за нелокального обращения к памяти Каждый вызов метода - обращение к дикту неймспейса с запросом соответствующего ключа (поиск в хеше)
    • "Все плохо"-2, скорость Динамическая типизация - проверка типов на каждой операции Reference counting - постоянные cache misses из-за нелокального обращения к памяти Каждый вызов метода - обращение к дикту неймспейса с запросом соответствующего ключа (поиск в хеше) Тяжелая структура фреймов стека и замыканий - долгие прологи и эпилоги на входах/выходах в методы и по раскрутке исключений
    • "Все плохо"-2, скорость Динамическая типизация - проверка типов на каждой операции Reference counting - постоянные cache misses из-за нелокального обращения к памяти Каждый вызов метода - обращение к дикту неймспейса с запросом соответствующего ключа (поиск в хеше) Тяжелая структура фреймов стека и замыканий - долгие прологи и эпилоги на входах/выходах в методы и по раскрутке исключений В клинических случаях доводилось видеть ускорение в 50 раз после переписывания на C
    • "Все плохо"-3, latency Stop-the-world garbage collector - на больших хипах задержка GC сверху не ограничена
    • "Все плохо"-3, latency Stop-the-world garbage collector - на больших хипах задержка GC сверху не ограничена GIL (глобальный мутекс на доступ к состоянию интерпретатора для всех потоков) - рост задержек при выполнении тяжелой логики другими потоками
    • Так ли все плохо? Правило 80/20 - в 20 процентах кода проводится 80 процентов времени, и эти 20 процентов можно писать на C/C++
    • Так ли все плохо? Правило 80/20 - в 20 процентах кода проводится 80 процентов времени, и эти 20 процентов можно писать на C/C++ Для остальных 80 процентов даже клиническое замедление в 50 раз (редко наблюдаемое на практике) часто допустимо - например, 0.01 с реакции на событие для пользователя неотличимы от 0.0002 с
    • Так ли все плохо? Правило 80/20 - в 20 процентах кода проводится 80 процентов времени, и эти 20 процентов можно писать на C/C++ Для остальных 80 процентов даже клиническое замедление в 50 раз (редко наблюдаемое на практике) часто допустимо - например, 0.01 с реакции на событие для пользователя неотличимы от 0.0002 с Памяти на современных смартфонах довольно много, и если пользоваться правильными инструментами (например, sqlite вместо “велосипедных” хранилищ и форматов), то разница в потреблении памяти составляет единицы мегабайт и более чем приемлима
    • Так ли все плохо? Вопрос действительно больших хипов на смартфонах пока не стоит
    • Так ли все плохо? Вопрос действительно больших хипов на смартфонах пока не стоит В действительно плохих случаях наличие reference counting позволяет отключать GC в критичные моменты - останутся только мемори лики от циклических ссылок
    • Так ли все плохо? Вопрос действительно больших хипов на смартфонах пока не стоит В действительно плохих случаях наличие reference counting позволяет отключать GC в критичные моменты - останутся только мемори лики от циклических ссылок При должной культуре программирования можно избавиться и от них, используя слабые ссылки, и при этом работать без GC
    • Так ли все плохо? Вопрос действительно больших хипов на смартфонах пока не стоит В действительно плохих случаях наличие reference counting позволяет отключать GC в критичные моменты - останутся только мемори лики от циклических ссылок При должной культуре программирования можно избавиться и от них, используя слабые ссылки, и при этом работать без GC Это не так нереально, как может показаться на первый взгляд - именно таким образом реализована серверная часть World of Tanks
    • Так ли все плохо? Вопрос действительно больших хипов на смартфонах пока не стоит В действительно плохих случаях наличие reference counting позволяет отключать GC в критичные моменты - останутся только мемори лики от циклических ссылок При должной культуре программирования можно избавиться и от них, используя слабые ссылки, и при этом работать без GC Это не так нереально, как может показаться на первый взгляд - именно таким образом реализована серверная часть World of Tanks Причем число мест, где понадобились слабые ссылки, можно пересчитать по пальцам
    • Так ли все плохо? Вопрос же задержки решается довольно кардинально - для Python очень много асинхронных библиотек, где проблема синхронизации потоков не стоит вообще
    • Так ли все плохо? Вопрос же задержки решается довольно кардинально - для Python очень много асинхронных библиотек, где проблема синхронизации потоков не стоит вообще Подробнее - чуть позже
    • Похоже, что все-таки терпимо Однако о названных особенностях забывать не стоит
    • Похоже, что все-таки терпимо Однако о названных особенностях забывать не стоит И ни в коем случае не заниматься преждевременной оптимизацией!
    • Похоже, что все-таки терпимо Однако о названных особенностях забывать не стоит И ни в коем случае не заниматься преждевременной оптимизацией! В случае динамических языков хитросплетение факторов весьма сложно, и без грамотного профайлинга можно сделать только хуже
    • Похоже, что все-таки терпимо Однако о названных особенностях забывать не стоит И ни в коем случае не заниматься преждевременной оптимизацией! В случае динамических языков хитросплетение факторов весьма сложно, и без грамотного профайлинга можно сделать только хуже Благо, для грамотного профайлинга есть все необходимое
    • Зачем так жить? Пока что из плюсов только code reuse между платформами
    • Зачем так жить? Пока что из плюсов только code reuse между платформами И может быть сервером (это если он есть)
    • Зачем так жить? Пока что из плюсов только code reuse между платформами И может быть сервером (это если он есть) Но при этом надо заниматься интеграцией, и бояться плохой производительности
    • Зачем так жить? Библиотека у Python приятная, ровно как и он сам как язык, но этим трудно удивить людей, знакомых с managed платформами
    • Зачем так жить? Библиотека у Python приятная, ровно как и он сам как язык, но этим трудно удивить людей, знакомых с managed платформами Попробую дать дополнительные доводы в пользу подхода, которые, на мой взгляд, оправдывают его не очень эффективную реализацию
    • Интерпретируемость Байткод Python для него такие же данные, как и все остальное
    • Интерпретируемость Байткод Python для него такие же данные, как и все остальное Его можно хранить в ресурсах, присылать по сети, компоновать из него классы
    • Интерпретируемость Байткод Python для него такие же данные, как и все остальное Его можно хранить в ресурсах, присылать по сети, компоновать из него классы Можно слегка подправить у пользователя с сервера расположение элементов UI, логику таймаутов, или нечто подобное, на что обычно жалко тратить целый апдейт
    • Интерпретируемость Байткод Python для него такие же данные, как и все остальное Его можно хранить в ресурсах, присылать по сети, компоновать из него классы Можно слегка подправить у пользователя с сервера расположение элементов UI, логику таймаутов, или нечто подобное, на что обычно жалко тратить целый апдейт Естественно, нельзя забывать про возможные уязвимости и адекватный сендбоксинг
    • Интроспекция Иерархию классов, определения методов, любые значения можно менять в рантайме
    • Интроспекция Иерархию классов, определения методов, любые значения можно менять в рантайме Очень полезно при отладке и первичной настройке
    • Интроспекция Иерархию классов, определения методов, любые значения можно менять в рантайме Очень полезно при отладке и первичной настройке Сильно сокращает compile/run/eval цикл
    • Интроспекция Иерархию классов, определения методов, любые значения можно менять в рантайме Очень полезно при отладке и первичной настройке Сильно сокращает compile/run/eval цикл Минимальная реализация - консоль через RunSimpleString
    • Интроспекция Иерархию классов, определения методов, любые значения можно менять в рантайме Очень полезно при отладке и первичной настройке Сильно сокращает compile/run/eval цикл Минимальная реализация - консоль через RunSimpleString Возможность манкипатчинга кода на лету без рестарта порою очень кстати
    • Интроспекция Иерархию классов, определения методов, любые значения можно менять в рантайме Очень полезно при отладке и первичной настройке Сильно сокращает compile/run/eval цикл Минимальная реализация - консоль через RunSimpleString Возможность манкипатчинга кода на лету без рестарта порою очень кстати Может заменить львиную долю одноразовых логов и “админок”
    • Отладка и профайлинг Можно потребовать оттрейсить несколько вызовов определенного метода
    • Отладка и профайлинг Можно потребовать оттрейсить несколько вызовов определенного метода Можно запросить подробную информацию о времени выполнения всех кодовых путей
    • Отладка и профайлинг Можно потребовать оттрейсить несколько вызовов определенного метода Можно запросить подробную информацию о времени выполнения всех кодовых путей Все это - на хосте (в нашем случае - на смартфоне)
    • Отладка и профайлинг Можно потребовать оттрейсить несколько вызовов определенного метода Можно запросить подробную информацию о времени выполнения всех кодовых путей Все это - на хосте (в нашем случае - на смартфоне) Причем в произвольный момент, и без рестарта приложения
    • Pickle - универсальная сериализация Все объекты Python могут быть сериализованы в единый формат - pickle
    • Pickle - универсальная сериализация Все объекты Python могут быть сериализованы в единый формат - pickle Формат можно расширить на типы модулей расширения
    • Pickle - универсальная сериализация Все объекты Python могут быть сериализованы в единый формат - pickle Формат можно расширить на типы модулей расширения Код сериализации писать не надо - все есть в рантайме
    • Pickle - универсальная сериализация Все объекты Python могут быть сериализованы в единый формат - pickle Формат можно расширить на типы модулей расширения Код сериализации писать не надо - все есть в рантайме Циклические ссылки не являются проблемой
    • Гибкое состояние Интерпретатор позволяет управлять своим состоянием в широких пределах
    • Гибкое состояние Интерпретатор позволяет управлять своим состоянием в широких пределах Через системные классы - стеком, сборщиком мусора, исключениями
    • Гибкое состояние Интерпретатор позволяет управлять своим состоянием в широких пределах Через системные классы - стеком, сборщиком мусора, исключениями Через специальные методы - поведением объектов
    • Гибкое состояние Интерпретатор позволяет управлять своим состоянием в широких пределах Через системные классы - стеком, сборщиком мусора, исключениями Через специальные методы - поведением объектов Remote procedure call, работающий полностью прозрачно - реальность, реализуемая за очень конечное время
    • Гибкое состояние Интерпретатор позволяет управлять своим состоянием в широких пределах Через системные классы - стеком, сборщиком мусора, исключениями Через специальные методы - поведением объектов Remote procedure call, работающий полностью прозрачно - реальность, реализуемая за очень конечное время Ровно как и green threads, реализованные библиотекой
    • Greenlet Выполнение любой специальным образом запущенной функции может быть прекращено и возобновлено в любой момент
    • Greenlet Выполнение любой специальным образом запущенной функции может быть прекращено и возобновлено в любой момент Как следствие, становятся возможны нетривиальные структуры управления
    • Greenlet Выполнение любой специальным образом запущенной функции может быть прекращено и возобновлено в любой момент Как следствие, становятся возможны нетривиальные структуры управления Например, внешне синхронный интерфейс к асинхронным API
    • Gevent Хрестоматийный пример - библиотека асинхронного сетевого взаимодействия Gevent
    • Gevent Хрестоматийный пример - библиотека асинхронного сетевого взаимодействия Gevent Под капотом - event-based API (epoll, kqueue, iocp)
    • Gevent Хрестоматийный пример - библиотека асинхронного сетевого взаимодействия Gevent Под капотом - event-based API (epoll, kqueue, iocp) Внешне же код выглядит, как синхронный сетевой код в отдельном потоке из учебника
    • Gevent Хрестоматийный пример - библиотека асинхронного сетевого взаимодействия Gevent Под капотом - event-based API (epoll, kqueue, iocp) Внешне же код выглядит, как синхронный сетевой код в отдельном потоке из учебника Каждый поток является “зеленым” (реализован через сохранение состояния интерпретатора), его overhead очень мал
    • Gevent Фактически код линейный, синхронный, простой
    • Gevent Фактически код линейный, синхронный, простой Без callbackов и FSM
    • Gevent Фактически код линейный, синхронный, простой Без callbackов и FSM (хотя под капотом оно именно так и работает)
    • Gevent Фактически код линейный, синхронный, простой Без callbackов и FSM (хотя под капотом оно именно так и работает) Это невероятно удобно, особенно в логике, где надо много ждать - UI, сеть
    • Зеленые потоки - больше примеров Таймеры - sleep() просто пробуждает гринлет, вместо того, чтобы объект, нуждающийся в таймауте, сам работал с коллбэками
    • Зеленые потоки - больше примеров Таймеры - sleep() просто пробуждает гринлет, вместо того, чтобы объект, нуждающийся в таймауте, сам работал с коллбэками Анимации - изменение накапливаемого значения в цикле со sleep выглядит куда интуитивнее логики на коллбэках
    • Зеленые потоки - больше примеров Таймеры - sleep() просто пробуждает гринлет, вместо того, чтобы объект, нуждающийся в таймауте, сам работал с коллбэками Анимации - изменение накапливаемого значения в цикле со sleep выглядит куда интуитивнее логики на коллбэках Игровой AI - сложное поведение очень просто “размазать” по тикам игрового мира, и при этом не изуродовать код
    • Зеленые потоки - больше примеров В литературе по теории языков программирования проблема уродования кода коллбэками называется inversion of control
    • Зеленые потоки - больше примеров В литературе по теории языков программирования проблема уродования кода коллбэками называется inversion of control Greenlet ее по большей части решает
    • Зеленые потоки - больше примеров В литературе по теории языков программирования проблема уродования кода коллбэками называется inversion of control Greenlet ее по большей части решает На мой взгляд, одна из особенностей Python, которая дает ему (наряду с Lua, Erlang и новым C#), существенные новые выразительные средства по сравнению с более ортодоксальными языками
    • Stackless Python Стоит посмотреть этот форк CPython, если идеи зеленых потоков вам близки
    • Stackless Python Стоит посмотреть этот форк CPython, если идеи зеленых потоков вам близки Вкратце - Greenlet на стероидах
    • Stackless Python Стоит посмотреть этот форк CPython, если идеи зеленых потоков вам близки Вкратце - Greenlet на стероидах Есть шедулер, хвостовая рекурсия, возможность переезда зеленых потоков между машинами (почти Erlang/OTP)
    • Stackless Python Стоит посмотреть этот форк CPython, если идеи зеленых потоков вам близки Вкратце - Greenlet на стероидах Есть шедулер, хвостовая рекурсия, возможность переезда зеленых потоков между машинами (почти Erlang/OTP) Success story - MMORPG Eve Online
    • Спасибо за внимание
    • Вопросы?