Встраивание Python в мобильные приложения – нюансы interoperation, новые подходы к разработке. Никита Лесников -
1. Встраивание Python в мобильные
приложения
нюансы interoperation, новые приемы разработки
Никита Лесников
2. Дисклеймер
Доклад носит общий характер, без нюансов
отдельных платформ
3. Дисклеймер
Доклад носит общий характер, без нюансов
отдельных платформ
Все описанные решения не “коробочные”, чтобы
велосипед поехал, надо существенно
поработать напильником
4. Дисклеймер
Доклад носит общий характер, без нюансов
отдельных платформ
Все описанные решения не “коробочные”, чтобы
велосипед поехал, надо существенно
поработать напильником
В простых случаях, где нет
многоплатформенности или серверной части,
многие описанные решения будут оверкилльны
5. Дисклеймер
Доклад носит общий характер, без нюансов
отдельных платформ
Все описанные решения не “коробочные”, чтобы
велосипед поехал, надо существенно
поработать напильником
В простых случаях, где нет
многоплатформенности или серверной части,
многие описанные решения будут оверкилльны
Не смущает вышесказанное? Тогда поехали...
6. Зоопарк ЯП
Языки программирования не являются “вещью в
себе”
7. Зоопарк ЯП
Языки программирования не являются “вещью в
себе”
Часто область применения определяет больше,
нежели синтаксис или дисциплина типизации
8. Зоопарк ЯП
Языки программирования не являются “вещью в
себе”
Часто область применения определяет больше,
нежели синтаксис или дисциплина типизации
В отдельных областях de facto сложились
решения, от которых отойти нельзя при всех
кажущихся недостатках
9. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
10. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
11. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
12. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
2. CSS - стилизация страниц
13. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
2. CSS - стилизация страниц
3. JavaScript - клиентское скриптование
14. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
2. CSS - стилизация страниц
3. JavaScript - клиентское скриптование
4. Что угодно еще - серверная часть
15. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
2. CSS - стилизация страниц
3. JavaScript - клиентское скриптование
4. Что угодно еще - серверная часть
Четыре языка для описания одной сущности!
16. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
2. CSS - стилизация страниц
3. JavaScript - клиентское скриптование
4. Что угодно еще - серверная часть
Четыре языка для описания одной сущности!
Организационный кошмар
17. Web - классический пример
Сколько языков необходимо, чтобы создать
типичное веб-приложение?
Попробуем посчитать:
1. HTML - разметка страниц
2. CSS - стилизация страниц
3. JavaScript - клиентское скриптование
4. Что угодно еще - серверная часть
Четыре языка для описания одной сущности!
Организационный кошмар
Повторное использование кода невозможно
18. Web - попытки решить проблему
node.js - возможность разработки серверной
логики на JavaScript (позволяет code reuse
между клиентской и серверной частями)
19. Web - попытки решить проблему
node.js - возможность разработки серверной
логики на JavaScript (позволяет code reuse
между клиентской и серверной частями)
шаблонизаторы - отделяют HTML-код страницы
от ее логического представления, делая
возможным смену представления без правки
бизнес-логики
20. Web - попытки решить проблему
node.js - возможность разработки серверной
логики на JavaScript (позволяет code reuse
между клиентской и серверной частями)
шаблонизаторы - отделяют HTML-код страницы
от ее логического представления, делая
возможным смену представления без правки
бизнес-логики
Объективные качества упомянутых подходов
лежат за рамками этого доклада
21. Мобильная разработка чем-то похожа...
Авторы кроссплатформенных приложений для
мобильных платформ сталкиваются с (почти той
же) проблемой
22. Мобильная разработка чем-то похожа...
Авторы кроссплатформенных приложений для
мобильных платформ сталкиваются с (почти той
же) проблемой
Разве что код надо переписывать один и тот же
на разных языках, а не компоновать единый
проект из разнородных кусочков
23. Мобильная разработка чем-то похожа...
Авторы кроссплатформенных приложений для
мобильных платформ сталкиваются с (почти той
же) проблемой
Разве что код надо переписывать один и тот же
на разных языках, а не компоновать единый
проект из разнородных кусочков
Java, Objective-C и C++ достаточно различны,
чтобы сделать автоматическое портирование
достаточно нетривиальным
24. Мобильная разработка чем-то похожа...
Авторы кроссплатформенных приложений для
мобильных платформ сталкиваются с (почти той
же) проблемой
Разве что код надо переписывать один и тот же
на разных языках, а не компоновать единый
проект из разнородных кусочков
Java, Objective-C и C++ достаточно различны,
чтобы сделать автоматическое портирование
достаточно нетривиальным
Даже поддержка native code многого не
гарантирует - Objective-C++ не совместим на
уровне лексера с C++03, на Android
non-POSIX-compliant-libc
25. Мобильная разработка чем-то похожа...
Авторы кроссплатформенных приложений для
мобильных платформ сталкиваются с (почти той
же) проблемой
Разве что код надо переписывать один и тот же
на разных языках, а не компоновать единый
проект из разнородных кусочков
Java, Objective-C и C++ достаточно различны,
чтобы сделать автоматическое портирование
достаточно нетривиальным
Даже поддержка native code многого не
гарантирует - Objective-C++ не совместим на
уровне лексера с C++03, на Android
non-POSIX-compliant-libc
Если у проекта есть серверная часть,
добавляются “языковые проблемы веба”
26. ...однако и чем-то различна
У всех платформ современных смартфонов, за
исключением Windows Phone 7, есть-таки общая
черта
27. ...однако и чем-то различна
У всех платформ современных смартфонов, за
исключением Windows Phone 7, есть-таки общая
черта
Как ни странно, это ANSI C
28. ...однако и чем-то различна
У всех платформ современных смартфонов, за
исключением Windows Phone 7, есть-таки общая
черта
Как ни странно, это ANSI C
Objective-C является его прямым
надмножеством, у Android с C изначально все
хорошо
29. ...однако и чем-то различна
У всех платформ современных смартфонов, за
исключением Windows Phone 7, есть-таки общая
черта
Как ни странно, это ANSI C
Objective-C является его прямым
надмножеством, у Android с C изначально все
хорошо
Разве что как язык C не слишком
воодушевляющ - подсчет битов является
последним делом, которым хочется заниматься
в большом кроссплатформенном проекте с и так
ограниченными ресурсами
30. ...однако и чем-то различна
У всех платформ современных смартфонов, за
исключением Windows Phone 7, есть-таки общая
черта
Как ни странно, это ANSI C
Objective-C является его прямым
надмножеством, у Android с C изначально все
хорошо
Разве что как язык C не слишком
воодушевляющ - подсчет битов является
последним делом, которым хочется заниматься
в большом кроссплатформенном проекте с и так
ограниченными ресурсами
Особенно, когда “высвободившаяся”
производительность изначально не нужна
31. Казалось бы, причем тут Python?
Python - интерпретируемый высокоуровневый
язык с динамической типизацией
32. Казалось бы, причем тут Python?
Python - интерпретируемый высокоуровневый
язык с динамической типизацией
ООП, интроспекция, метапрограммирование -
все в наличии
33. Казалось бы, причем тут Python?
Python - интерпретируемый высокоуровневый
язык с динамической типизацией
ООП, интроспекция, метапрограммирование -
все в наличии
Куча крутых библиотек, в том числе в базовой
поставке (что отражено в девизе - batteries
included)
34. Казалось бы, причем тут Python?
Python - интерпретируемый высокоуровневый
язык с динамической типизацией
ООП, интроспекция, метапрограммирование -
все в наличии
Куча крутых библиотек, в том числе в базовой
поставке (что отражено в девизе - batteries
included)
Простой API для C, что автоматически означает
простой API для чего угодно
35. Казалось бы, причем тут Python?
Python - интерпретируемый высокоуровневый
язык с динамической типизацией
ООП, интроспекция, метапрограммирование -
все в наличии
Куча крутых библиотек, в том числе в базовой
поставке (что отражено в девизе - batteries
included)
Простой API для C, что автоматически означает
простой API для чего угодно
Весь рантайм также написан на С и
представляет из себя самодостаточную систему
для разработки, отладки и выполнения кода
36. Казалось бы, причем тут Python?
Python - интерпретируемый высокоуровневый
язык с динамической типизацией
ООП, интроспекция, метапрограммирование -
все в наличии
Куча крутых библиотек, в том числе в базовой
поставке (что отражено в девизе - batteries
included)
Простой API для C, что автоматически означает
простой API для чего угодно
Весь рантайм также написан на С и
представляет из себя самодостаточную систему
для разработки, отладки и выполнения кода
Этот самый “весь рантайм” можно сделать
частью вашего приложения
37. Как это можно использовать?
Писать на Python большую часть
слабокритичного к платформенным нюансам и
производительности кода
38. Как это можно использовать?
Писать на Python большую часть
слабокритичного к платформенным нюансам и
производительности кода
Как следствие, нативная и/или
платформозависимая часть сократится
39. Как это можно использовать?
Писать на Python большую часть
слабокритичного к платформенным нюансам и
производительности кода
Как следствие, нативная и/или
платформозависимая часть сократится
Общее количество кода станет сильно меньше,
что всегда хорошо
40. Как это можно использовать?
Писать на Python большую часть
слабокритичного к платформенным нюансам и
производительности кода
Как следствие, нативная и/или
платформозависимая часть сократится
Общее количество кода станет сильно меньше,
что всегда хорошо
При адекватном подходе производительность
будет более чем приемлимой
42. Почему именно Python?
Больше вопрос вкуса
Хорошая альтернатива - Lua, легче
встраивается, но и стандартная библитека
поменьше (“из коробки” ее фактически нет)
43. Почему именно Python?
Больше вопрос вкуса
Хорошая альтернатива - Lua, легче
встраивается, но и стандартная библитека
поменьше (“из коробки” ее фактически нет)
Python очень консистентен и предсказуем -
“неожиданностей” не бывает почти никогда при
должном понимании основных концепций
44. Почему именно Python?
Больше вопрос вкуса
Хорошая альтернатива - Lua, легче
встраивается, но и стандартная библитека
поменьше (“из коробки” ее фактически нет)
Python очень консистентен и предсказуем -
“неожиданностей” не бывает почти никогда при
должном понимании основных концепций
“Должное понимание” - не некое абстрактное
понятие, как, например, мифическое “хорошее
знание C++”, оно вполне достижимо за очень
ограниченный срок
45. Почему именно Python?
Больше вопрос вкуса
Хорошая альтернатива - Lua, легче
встраивается, но и стандартная библитека
поменьше (“из коробки” ее фактически нет)
Python очень консистентен и предсказуем -
“неожиданностей” не бывает почти никогда при
должном понимании основных концепций
“Должное понимание” - не некое абстрактное
понятие, как, например, мифическое “хорошее
знание C++”, оно вполне достижимо за очень
ограниченный срок
По опыту wargaming.net, программисты без
прежнего знания Python, но с сильным
бэкграундом в других областях, осваиваются за
считанные дни
46. О чем я расскажу
Цель - не перечислить написать reference
manual по embedding API, а показать одно из
возможных решений целого спектра проблем
47. О чем я расскажу
Цель - не перечислить написать reference
manual по embedding API, а показать одно из
возможных решений целого спектра проблем
Не знаете Python? Это не страшно, его знание
тут некритично - повествование больше на
уровне идей
48. О чем я расскажу
Цель - не перечислить написать reference
manual по embedding API, а показать одно из
возможных решений целого спектра проблем
Не знаете Python? Это не страшно, его знание
тут некритично - повествование больше на
уровне идей
Мне тоже по ходу можно (и нужно) задавать
вопросы, если что-то непонятно
49. Собственно по теме доклада :)
Берем source distribution c исходниками Python
50. Собственно по теме доклада :)
Берем source distribution c исходниками Python
Собираем статическую библиотеку, отключив
все ненужное
51. Собственно по теме доклада :)
Берем source distribution c исходниками Python
Собираем статическую библиотеку, отключив
все ненужное
“Все ненужное” - это почти все. И чем более
почти, тем безболезненнее проходит сборка -
core python собирается при помощи autotools и
компилятора C, без внешних зависимостей
вообще
52. Собственно по теме доклада :)
Берем source distribution c исходниками Python
Собираем статическую библиотеку, отключив
все ненужное
“Все ненужное” - это почти все. И чем более
почти, тем безболезненнее проходит сборка -
core python собирается при помощи autotools и
компилятора C, без внешних зависимостей
вообще
Проблемы могут быть, но все решается быстрым
поиском по core development документации,
stackoverflow и подобным ресурсам
53. Собственно по теме доклада :)
Берем source distribution c исходниками Python
Собираем статическую библиотеку, отключив
все ненужное
“Все ненужное” - это почти все. И чем более
почти, тем безболезненнее проходит сборка -
core python собирается при помощи autotools и
компилятора C, без внешних зависимостей
вообще
Проблемы могут быть, но все решается быстрым
поиском по core development документации,
stackoverflow и подобным ресурсам
Большинство проблем лечатся ключами к
configure
54. Собственно по теме доклада :)
Берем source distribution c исходниками Python
Собираем статическую библиотеку, отключив
все ненужное
“Все ненужное” - это почти все. И чем более
почти, тем безболезненнее проходит сборка -
core python собирается при помощи autotools и
компилятора C, без внешних зависимостей
вообще
Проблемы могут быть, но все решается быстрым
поиском по core development документации,
stackoverflow и подобным ресурсам
Большинство проблем лечатся ключами к
configure
Даже core сборка содержит много крутых
вещей (коллекции, регэкспы, хеши, даты,
сериализацию, адекватный Unicode)
55. Собственно по теме доклада :)
Берем source distribution c исходниками Python
Собираем статическую библиотеку, отключив
все ненужное
“Все ненужное” - это почти все. И чем более
почти, тем безболезненнее проходит сборка -
core python собирается при помощи autotools и
компилятора C, без внешних зависимостей
вообще
Проблемы могут быть, но все решается быстрым
поиском по core development документации,
stackoverflow и подобным ресурсам
Большинство проблем лечатся ключами к
configure
Даже core сборка содержит много крутых
вещей (коллекции, регэкспы, хеши, даты,
сериализацию, адекватный Unicode)
Это всегда допустимый fallback
57. libPython.a есть? идем дальше
Настраиваем линковку с этим блобом
Делаем вот так:
#include <Python . h>
void execute_python_code ( )
{
Py_Initialize ();
PyRun_SimpleString ( "python_code_here" ) ;
Py_Finalize ( ) ;
}
58. libPython.a есть? идем дальше
Настраиваем линковку с этим блобом
Делаем вот так:
#include <Python . h>
void execute_python_code ( )
{
Py_Initialize ();
PyRun_SimpleString ( "python_code_here" ) ;
Py_Finalize ( ) ;
}
Все, мы исполнили код на Python
60. Как-то слишком просто?
Ну, это самый “высокоуровневый” вариант
Годится, например, для Python-консоли времени
выполнения
61. Как-то слишком просто?
Ну, это самый “высокоуровневый” вариант
Годится, например, для Python-консоли времени
выполнения
Есть более тонкие инструменты
62. Как-то слишком просто?
Ну, это самый “высокоуровневый” вариант
Годится, например, для Python-консоли времени
выполнения
Есть более тонкие инструменты
Но суть та же:
63. Как-то слишком просто?
Ну, это самый “высокоуровневый” вариант
Годится, например, для Python-консоли времени
выполнения
Есть более тонкие инструменты
Но суть та же:
1. Если в другом потоке, лочим мутекс стейта
64. Как-то слишком просто?
Ну, это самый “высокоуровневый” вариант
Годится, например, для Python-консоли времени
выполнения
Есть более тонкие инструменты
Но суть та же:
1. Если в другом потоке, лочим мутекс стейта
2. Манипулируем состоянием, вызываем методы
65. Как-то слишком просто?
Ну, это самый “высокоуровневый” вариант
Годится, например, для Python-консоли времени
выполнения
Есть более тонкие инструменты
Но суть та же:
1. Если в другом потоке, лочим мутекс стейта
2. Манипулируем состоянием, вызываем методы
3. Концептуально, все вызовы “в один конец” - из C
в Python
66. А в обратную сторону как?
Core python может не осилить реализацию
многих компонент приложения, ибо там особые
интерфейсы, имеющиеся в нативном коде, но
“прозрачно” недоступные
67. А в обратную сторону как?
Core python может не осилить реализацию
многих компонент приложения, ибо там особые
интерфейсы, имеющиеся в нативном коде, но
“прозрачно” недоступные
Плохо, писать много “скучного” кода на Python -
наша цель
68. А в обратную сторону как?
Core python может не осилить реализацию
многих компонент приложения, ибо там особые
интерфейсы, имеющиеся в нативном коде, но
“прозрачно” недоступные
Плохо, писать много “скучного” кода на Python -
наша цель
Да и спускать критичные по скорости ботлнеки
в C/C++ тоже хотелось бы для спокойствия
69. А в обратную сторону как?
Core python может не осилить реализацию
многих компонент приложения, ибо там особые
интерфейсы, имеющиеся в нативном коде, но
“прозрачно” недоступные
Плохо, писать много “скучного” кода на Python -
наша цель
Да и спускать критичные по скорости ботлнеки
в C/C++ тоже хотелось бы для спокойствия
Это решается написанием модулей расширения
70. Некоторые детали
Придумываем для каждой сущности аналог в
рантайме Python
71. Некоторые детали
Придумываем для каждой сущности аналог в
рантайме Python
Пишем унылые функции-передергивалки,
которые возьмут на себя bookkeeping
референс-каунтинга, маршаллинга объектов
Python в С и обратно
72. Некоторые детали
Придумываем для каждой сущности аналог в
рантайме Python
Пишем унылые функции-передергивалки,
которые возьмут на себя bookkeeping
референс-каунтинга, маршаллинга объектов
Python в С и обратно
Заполняем сишную структуру, которая задаст
интерпретатору интерфейс модуля
73. Некоторые детали
Придумываем для каждой сущности аналог в
рантайме Python
Пишем унылые функции-передергивалки,
которые возьмут на себя bookkeeping
референс-каунтинга, маршаллинга объектов
Python в С и обратно
Заполняем сишную структуру, которая задаст
интерпретатору интерфейс модуля
Вызовем функцию-инициализатор модуля после
старта интерпретатора
74. Некоторые детали
Придумываем для каждой сущности аналог в
рантайме Python
Пишем унылые функции-передергивалки,
которые возьмут на себя bookkeeping
референс-каунтинга, маршаллинга объектов
Python в С и обратно
Заполняем сишную структуру, которая задаст
интерпретатору интерфейс модуля
Вызовем функцию-инициализатор модуля после
старта интерпретатора
Все, можно вызывать нативные функции из
кода на Python.
75. Некоторые детали
Придумываем для каждой сущности аналог в
рантайме Python
Пишем унылые функции-передергивалки,
которые возьмут на себя bookkeeping
референс-каунтинга, маршаллинга объектов
Python в С и обратно
Заполняем сишную структуру, которая задаст
интерпретатору интерфейс модуля
Вызовем функцию-инициализатор модуля после
старта интерпретатора
Все, можно вызывать нативные функции из
кода на Python.
В детали не буду вдаваться из-за регламента,
но поверьте, там все дуболомно просто, разве
что очень много бойлерплейта
76. Сторонние модули
То же самое касается чужих модулей,
распространяемых в исходниках
77. Сторонние модули
То же самое касается чужих модулей,
распространяемых в исходниках
Во “взрослых” применениях они обычно
собираются в shared library (.dll, .so, .dylib),
однако никто не мешает слинковаться с ними
статически и вызвать функцию-инициализатор
вручную
78. Сторонние модули
То же самое касается чужих модулей,
распространяемых в исходниках
Во “взрослых” применениях они обычно
собираются в shared library (.dll, .so, .dylib),
однако никто не мешает слинковаться с ними
статически и вызвать функцию-инициализатор
вручную
Не стоит стесняться так делать
79. Сторонние модули
То же самое касается чужих модулей,
распространяемых в исходниках
Во “взрослых” применениях они обычно
собираются в shared library (.dll, .so, .dylib),
однако никто не мешает слинковаться с ними
статически и вызвать функцию-инициализатор
вручную
Не стоит стесняться так делать
Идеальная на мой взгляд ситуация - когда код
сразу вызывает питоновский аналог main, и
лишь самые низкоуровневые вызовы приходят
обратно на нативный уровень
80. Сторонние модули
То же самое касается чужих модулей,
распространяемых в исходниках
Во “взрослых” применениях они обычно
собираются в shared library (.dll, .so, .dylib),
однако никто не мешает слинковаться с ними
статически и вызвать функцию-инициализатор
вручную
Не стоит стесняться так делать
Идеальная на мой взгляд ситуация - когда код
сразу вызывает питоновский аналог main, и
лишь самые низкоуровневые вызовы приходят
обратно на нативный уровень
Нативный уровень уменьшается по максимуму,
и портировать его намного проще (код на
Python ведь переписывать не нужно)
81. GameDev - чуть ли не идеальный случай
Интерфейсов мало - OpenGL, OpenAL, тач,
несколько дополнительных ивентов
82. GameDev - чуть ли не идеальный случай
Интерфейсов мало - OpenGL, OpenAL, тач,
несколько дополнительных ивентов
Хранилище ресурсов, сеть, UI - можно часто
шарить, ведь они все равно “свои”
83. GameDev - чуть ли не идеальный случай
Интерфейсов мало - OpenGL, OpenAL, тач,
несколько дополнительных ивентов
Хранилище ресурсов, сеть, UI - можно часто
шарить, ведь они все равно “свои”
Тяжелые вещи вроде AI и поиска путей
спускаются в нативные модули
84. SWIG - пишем обвязку проще
SWIG - генератор связующего кода по слегка
размеченному “файлу интерфейса” для кода на
C/C++.
85. SWIG - пишем обвязку проще
SWIG - генератор связующего кода по слегка
размеченному “файлу интерфейса” для кода на
C/C++.
Фактически способен по .h файлу
сгенерировать для сишных функций полный
аналог, с адекватным сопоставлением типов
(вроде превращения int* в список чисел)
86. SWIG - пишем обвязку проще
SWIG - генератор связующего кода по слегка
размеченному “файлу интерфейса” для кода на
C/C++.
Фактически способен по .h файлу
сгенерировать для сишных функций полный
аналог, с адекватным сопоставлением типов
(вроде превращения int* в список чисел)
С memory policy тоже все хорошо - сишные
объекты наследуют поведение reference counted
объектов Python.
87. SWIG - пишем обвязку проще
SWIG - генератор связующего кода по слегка
размеченному “файлу интерфейса” для кода на
C/C++.
Фактически способен по .h файлу
сгенерировать для сишных функций полный
аналог, с адекватным сопоставлением типов
(вроде превращения int* в список чисел)
С memory policy тоже все хорошо - сишные
объекты наследуют поведение reference counted
объектов Python.
Умеет “зеркалировать” и иерархии классов C++
88. SWIG - пишем обвязку проще
SWIG - генератор связующего кода по слегка
размеченному “файлу интерфейса” для кода на
C/C++.
Фактически способен по .h файлу
сгенерировать для сишных функций полный
аналог, с адекватным сопоставлением типов
(вроде превращения int* в список чисел)
С memory policy тоже все хорошо - сишные
объекты наследуют поведение reference counted
объектов Python.
Умеет “зеркалировать” и иерархии классов C++
Радикально снимает вопрос написания кода
взаимодействия Python-C
89. 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 " ) )
90. boost::python
Темплейтная библиотека для C++,
добивающаяся аналогичных целей
91. boost::python
Темплейтная библиотека для C++,
добивающаяся аналогичных целей
По целям аналогична SWIG, но достигает их
другим способом
92. boost::python
Темплейтная библиотека для C++,
добивающаяся аналогичных целей
По целям аналогична SWIG, но достигает их
другим способом
Может быть удобнее, когда зависимость от
boost не пугает, а усложнение процесса сборки
еще одной утилитой (SWIG) нежелательно
93. boost::python
Темплейтная библиотека для C++,
добивающаяся аналогичных целей
По целям аналогична SWIG, но достигает их
другим способом
Может быть удобнее, когда зависимость от
boost не пугает, а усложнение процесса сборки
еще одной утилитой (SWIG) нежелательно
Интерфейсы задаются макросами
препроцессора в коде
94. boost::python
Темплейтная библиотека для C++,
добивающаяся аналогичных целей
По целям аналогична SWIG, но достигает их
другим способом
Может быть удобнее, когда зависимость от
boost не пугает, а усложнение процесса сборки
еще одной утилитой (SWIG) нежелательно
Интерфейсы задаются макросами
препроцессора в коде
В отличие от SWIG позволяет пользоваться
функциями embedding API напрямую, что может
быть важно (SWIG, впрочем, не запрещает тоже,
однако править сгенерированный код
методологически неправильно)
95. Производительность
Зная способы размещения кода как в нативной,
так и в скриптовой части приложения, надо
уметь прикидывать, какую подсистему куда
отнести
96. Производительность
Зная способы размещения кода как в нативной,
так и в скриптовой части приложения, надо
уметь прикидывать, какую подсистему куда
отнести
Следует представлять себе запросы скриптов к
памяти и процессорному времени
97. Производительность
Зная способы размещения кода как в нативной,
так и в скриптовой части приложения, надо
уметь прикидывать, какую подсистему куда
отнести
Следует представлять себе запросы скриптов к
памяти и процессорному времени
Там все очень плохо
98. "Все плохо"-1, память
В зависимости от разрядности интерпретатора
и наличия отладочных опций при сборке размер
объекта Python может сильно плавать, но все
равно не может быть меньше двух указателей
99. "Все плохо"-1, память
В зависимости от разрядности интерпретатора
и наличия отладочных опций при сборке размер
объекта Python может сильно плавать, но все
равно не может быть меньше двух указателей
В Python все - объект
100. "Все плохо"-1, память
В зависимости от разрядности интерпретатора
и наличия отладочных опций при сборке размер
объекта Python может сильно плавать, но все
равно не может быть меньше двух указателей
В Python все - объект
int размером 30 байт - это нормально
101. "Все плохо"-1, память
В зависимости от разрядности интерпретатора
и наличия отладочных опций при сборке размер
объекта Python может сильно плавать, но все
равно не может быть меньше двух указателей
В Python все - объект
int размером 30 байт - это нормально
Инстансы классов (насколько это понятие
применимо к Python) - часто от 300 байт
103. "Все плохо"-2, скорость
Динамическая типизация - проверка типов на
каждой операции
Reference counting - постоянные cache misses
из-за нелокального обращения к памяти
104. "Все плохо"-2, скорость
Динамическая типизация - проверка типов на
каждой операции
Reference counting - постоянные cache misses
из-за нелокального обращения к памяти
Каждый вызов метода - обращение к дикту
неймспейса с запросом соответствующего
ключа (поиск в хеше)
105. "Все плохо"-2, скорость
Динамическая типизация - проверка типов на
каждой операции
Reference counting - постоянные cache misses
из-за нелокального обращения к памяти
Каждый вызов метода - обращение к дикту
неймспейса с запросом соответствующего
ключа (поиск в хеше)
Тяжелая структура фреймов стека и замыканий
- долгие прологи и эпилоги на входах/выходах в
методы и по раскрутке исключений
106. "Все плохо"-2, скорость
Динамическая типизация - проверка типов на
каждой операции
Reference counting - постоянные cache misses
из-за нелокального обращения к памяти
Каждый вызов метода - обращение к дикту
неймспейса с запросом соответствующего
ключа (поиск в хеше)
Тяжелая структура фреймов стека и замыканий
- долгие прологи и эпилоги на входах/выходах в
методы и по раскрутке исключений
В клинических случаях доводилось видеть
ускорение в 50 раз после переписывания на C
107. "Все плохо"-3, latency
Stop-the-world garbage collector - на больших
хипах задержка GC сверху не ограничена
108. "Все плохо"-3, latency
Stop-the-world garbage collector - на больших
хипах задержка GC сверху не ограничена
GIL (глобальный мутекс на доступ к состоянию
интерпретатора для всех потоков) - рост
задержек при выполнении тяжелой логики
другими потоками
109. Так ли все плохо?
Правило 80/20 - в 20 процентах кода проводится
80 процентов времени, и эти 20 процентов
можно писать на C/C++
110. Так ли все плохо?
Правило 80/20 - в 20 процентах кода проводится
80 процентов времени, и эти 20 процентов
можно писать на C/C++
Для остальных 80 процентов даже клиническое
замедление в 50 раз (редко наблюдаемое на
практике) часто допустимо - например, 0.01 с
реакции на событие для пользователя
неотличимы от 0.0002 с
111. Так ли все плохо?
Правило 80/20 - в 20 процентах кода проводится
80 процентов времени, и эти 20 процентов
можно писать на C/C++
Для остальных 80 процентов даже клиническое
замедление в 50 раз (редко наблюдаемое на
практике) часто допустимо - например, 0.01 с
реакции на событие для пользователя
неотличимы от 0.0002 с
Памяти на современных смартфонах довольно
много, и если пользоваться правильными
инструментами (например, sqlite вместо
“велосипедных” хранилищ и форматов), то
разница в потреблении памяти составляет
единицы мегабайт и более чем приемлима
112. Так ли все плохо?
Вопрос действительно больших хипов на
смартфонах пока не стоит
113. Так ли все плохо?
Вопрос действительно больших хипов на
смартфонах пока не стоит
В действительно плохих случаях наличие
reference counting позволяет отключать GC в
критичные моменты - останутся только мемори
лики от циклических ссылок
114. Так ли все плохо?
Вопрос действительно больших хипов на
смартфонах пока не стоит
В действительно плохих случаях наличие
reference counting позволяет отключать GC в
критичные моменты - останутся только мемори
лики от циклических ссылок
При должной культуре программирования
можно избавиться и от них, используя слабые
ссылки, и при этом работать без GC
115. Так ли все плохо?
Вопрос действительно больших хипов на
смартфонах пока не стоит
В действительно плохих случаях наличие
reference counting позволяет отключать GC в
критичные моменты - останутся только мемори
лики от циклических ссылок
При должной культуре программирования
можно избавиться и от них, используя слабые
ссылки, и при этом работать без GC
Это не так нереально, как может показаться на
первый взгляд - именно таким образом
реализована серверная часть World of Tanks
116. Так ли все плохо?
Вопрос действительно больших хипов на
смартфонах пока не стоит
В действительно плохих случаях наличие
reference counting позволяет отключать GC в
критичные моменты - останутся только мемори
лики от циклических ссылок
При должной культуре программирования
можно избавиться и от них, используя слабые
ссылки, и при этом работать без GC
Это не так нереально, как может показаться на
первый взгляд - именно таким образом
реализована серверная часть World of Tanks
Причем число мест, где понадобились слабые
ссылки, можно пересчитать по пальцам
117. Так ли все плохо?
Вопрос же задержки решается довольно
кардинально - для Python очень много
асинхронных библиотек, где проблема
синхронизации потоков не стоит вообще
118. Так ли все плохо?
Вопрос же задержки решается довольно
кардинально - для Python очень много
асинхронных библиотек, где проблема
синхронизации потоков не стоит вообще
Подробнее - чуть позже
120. Похоже, что все-таки терпимо
Однако о названных особенностях забывать не
стоит
И ни в коем случае не заниматься
преждевременной оптимизацией!
121. Похоже, что все-таки терпимо
Однако о названных особенностях забывать не
стоит
И ни в коем случае не заниматься
преждевременной оптимизацией!
В случае динамических языков хитросплетение
факторов весьма сложно, и без грамотного
профайлинга можно сделать только хуже
122. Похоже, что все-таки терпимо
Однако о названных особенностях забывать не
стоит
И ни в коем случае не заниматься
преждевременной оптимизацией!
В случае динамических языков хитросплетение
факторов весьма сложно, и без грамотного
профайлинга можно сделать только хуже
Благо, для грамотного профайлинга есть все
необходимое
123. Зачем так жить?
Пока что из плюсов только code reuse между
платформами
124. Зачем так жить?
Пока что из плюсов только code reuse между
платформами
И может быть сервером (это если он есть)
125. Зачем так жить?
Пока что из плюсов только code reuse между
платформами
И может быть сервером (это если он есть)
Но при этом надо заниматься интеграцией, и
бояться плохой производительности
126. Зачем так жить?
Библиотека у Python приятная, ровно как и он
сам как язык, но этим трудно удивить людей,
знакомых с managed платформами
127. Зачем так жить?
Библиотека у Python приятная, ровно как и он
сам как язык, но этим трудно удивить людей,
знакомых с managed платформами
Попробую дать дополнительные доводы в
пользу подхода, которые, на мой взгляд,
оправдывают его не очень эффективную
реализацию
128. Интерпретируемость
Байткод Python для него такие же данные, как и
все остальное
129. Интерпретируемость
Байткод Python для него такие же данные, как и
все остальное
Его можно хранить в ресурсах, присылать по
сети, компоновать из него классы
130. Интерпретируемость
Байткод Python для него такие же данные, как и
все остальное
Его можно хранить в ресурсах, присылать по
сети, компоновать из него классы
Можно слегка подправить у пользователя с
сервера расположение элементов UI, логику
таймаутов, или нечто подобное, на что обычно
жалко тратить целый апдейт
131. Интерпретируемость
Байткод Python для него такие же данные, как и
все остальное
Его можно хранить в ресурсах, присылать по
сети, компоновать из него классы
Можно слегка подправить у пользователя с
сервера расположение элементов UI, логику
таймаутов, или нечто подобное, на что обычно
жалко тратить целый апдейт
Естественно, нельзя забывать про возможные
уязвимости и адекватный сендбоксинг
132. Интроспекция
Иерархию классов, определения методов,
любые значения можно менять в рантайме
133. Интроспекция
Иерархию классов, определения методов,
любые значения можно менять в рантайме
Очень полезно при отладке и первичной
настройке
134. Интроспекция
Иерархию классов, определения методов,
любые значения можно менять в рантайме
Очень полезно при отладке и первичной
настройке
Сильно сокращает compile/run/eval цикл
135. Интроспекция
Иерархию классов, определения методов,
любые значения можно менять в рантайме
Очень полезно при отладке и первичной
настройке
Сильно сокращает compile/run/eval цикл
Минимальная реализация - консоль через
RunSimpleString
136. Интроспекция
Иерархию классов, определения методов,
любые значения можно менять в рантайме
Очень полезно при отладке и первичной
настройке
Сильно сокращает compile/run/eval цикл
Минимальная реализация - консоль через
RunSimpleString
Возможность манкипатчинга кода на лету без
рестарта порою очень кстати
137. Интроспекция
Иерархию классов, определения методов,
любые значения можно менять в рантайме
Очень полезно при отладке и первичной
настройке
Сильно сокращает compile/run/eval цикл
Минимальная реализация - консоль через
RunSimpleString
Возможность манкипатчинга кода на лету без
рестарта порою очень кстати
Может заменить львиную долю одноразовых
логов и “админок”
138. Отладка и профайлинг
Можно потребовать оттрейсить несколько
вызовов определенного метода
139. Отладка и профайлинг
Можно потребовать оттрейсить несколько
вызовов определенного метода
Можно запросить подробную информацию о
времени выполнения всех кодовых путей
140. Отладка и профайлинг
Можно потребовать оттрейсить несколько
вызовов определенного метода
Можно запросить подробную информацию о
времени выполнения всех кодовых путей
Все это - на хосте (в нашем случае - на
смартфоне)
141. Отладка и профайлинг
Можно потребовать оттрейсить несколько
вызовов определенного метода
Можно запросить подробную информацию о
времени выполнения всех кодовых путей
Все это - на хосте (в нашем случае - на
смартфоне)
Причем в произвольный момент, и без рестарта
приложения
142. Pickle - универсальная сериализация
Все объекты Python могут быть сериализованы в
единый формат - pickle
143. Pickle - универсальная сериализация
Все объекты Python могут быть сериализованы в
единый формат - pickle
Формат можно расширить на типы модулей
расширения
144. Pickle - универсальная сериализация
Все объекты Python могут быть сериализованы в
единый формат - pickle
Формат можно расширить на типы модулей
расширения
Код сериализации писать не надо - все есть в
рантайме
145. Pickle - универсальная сериализация
Все объекты Python могут быть сериализованы в
единый формат - pickle
Формат можно расширить на типы модулей
расширения
Код сериализации писать не надо - все есть в
рантайме
Циклические ссылки не являются проблемой
146. Гибкое состояние
Интерпретатор позволяет управлять своим
состоянием в широких пределах
147. Гибкое состояние
Интерпретатор позволяет управлять своим
состоянием в широких пределах
Через системные классы - стеком, сборщиком
мусора, исключениями
148. Гибкое состояние
Интерпретатор позволяет управлять своим
состоянием в широких пределах
Через системные классы - стеком, сборщиком
мусора, исключениями
Через специальные методы - поведением
объектов
149. Гибкое состояние
Интерпретатор позволяет управлять своим
состоянием в широких пределах
Через системные классы - стеком, сборщиком
мусора, исключениями
Через специальные методы - поведением
объектов
Remote procedure call, работающий полностью
прозрачно - реальность, реализуемая за очень
конечное время
150. Гибкое состояние
Интерпретатор позволяет управлять своим
состоянием в широких пределах
Через системные классы - стеком, сборщиком
мусора, исключениями
Через специальные методы - поведением
объектов
Remote procedure call, работающий полностью
прозрачно - реальность, реализуемая за очень
конечное время
Ровно как и green threads, реализованные
библиотекой
151. Greenlet
Выполнение любой специальным образом
запущенной функции может быть прекращено и
возобновлено в любой момент
152. Greenlet
Выполнение любой специальным образом
запущенной функции может быть прекращено и
возобновлено в любой момент
Как следствие, становятся возможны
нетривиальные структуры управления
153. Greenlet
Выполнение любой специальным образом
запущенной функции может быть прекращено и
возобновлено в любой момент
Как следствие, становятся возможны
нетривиальные структуры управления
Например, внешне синхронный интерфейс к
асинхронным API
154. Gevent
Хрестоматийный пример - библиотека
асинхронного сетевого взаимодействия Gevent
155. Gevent
Хрестоматийный пример - библиотека
асинхронного сетевого взаимодействия Gevent
Под капотом - event-based API (epoll, kqueue,
iocp)
156. Gevent
Хрестоматийный пример - библиотека
асинхронного сетевого взаимодействия Gevent
Под капотом - event-based API (epoll, kqueue,
iocp)
Внешне же код выглядит, как синхронный
сетевой код в отдельном потоке из учебника
157. Gevent
Хрестоматийный пример - библиотека
асинхронного сетевого взаимодействия Gevent
Под капотом - event-based API (epoll, kqueue,
iocp)
Внешне же код выглядит, как синхронный
сетевой код в отдельном потоке из учебника
Каждый поток является “зеленым” (реализован
через сохранение состояния интерпретатора),
его overhead очень мал
158. Gevent
Фактически код линейный, синхронный, простой
159. Gevent
Фактически код линейный, синхронный, простой
Без callbackов и FSM
160. Gevent
Фактически код линейный, синхронный, простой
Без callbackов и FSM
(хотя под капотом оно именно так и работает)
161. Gevent
Фактически код линейный, синхронный, простой
Без callbackов и FSM
(хотя под капотом оно именно так и работает)
Это невероятно удобно, особенно в логике, где
надо много ждать - UI, сеть
162. Зеленые потоки - больше примеров
Таймеры - sleep() просто пробуждает гринлет,
вместо того, чтобы объект, нуждающийся в
таймауте, сам работал с коллбэками
163. Зеленые потоки - больше примеров
Таймеры - sleep() просто пробуждает гринлет,
вместо того, чтобы объект, нуждающийся в
таймауте, сам работал с коллбэками
Анимации - изменение накапливаемого
значения в цикле со sleep выглядит куда
интуитивнее логики на коллбэках
164. Зеленые потоки - больше примеров
Таймеры - sleep() просто пробуждает гринлет,
вместо того, чтобы объект, нуждающийся в
таймауте, сам работал с коллбэками
Анимации - изменение накапливаемого
значения в цикле со sleep выглядит куда
интуитивнее логики на коллбэках
Игровой AI - сложное поведение очень просто
“размазать” по тикам игрового мира, и при этом
не изуродовать код
165. Зеленые потоки - больше примеров
В литературе по теории языков
программирования проблема уродования кода
коллбэками называется inversion of control
166. Зеленые потоки - больше примеров
В литературе по теории языков
программирования проблема уродования кода
коллбэками называется inversion of control
Greenlet ее по большей части решает
167. Зеленые потоки - больше примеров
В литературе по теории языков
программирования проблема уродования кода
коллбэками называется inversion of control
Greenlet ее по большей части решает
На мой взгляд, одна из особенностей Python,
которая дает ему (наряду с Lua, Erlang и новым
C#), существенные новые выразительные
средства по сравнению с более
ортодоксальными языками
168. Stackless Python
Стоит посмотреть этот форк CPython, если идеи
зеленых потоков вам близки
169. Stackless Python
Стоит посмотреть этот форк CPython, если идеи
зеленых потоков вам близки
Вкратце - Greenlet на стероидах
170. Stackless Python
Стоит посмотреть этот форк CPython, если идеи
зеленых потоков вам близки
Вкратце - Greenlet на стероидах
Есть шедулер, хвостовая рекурсия,
возможность переезда зеленых потоков между
машинами (почти Erlang/OTP)
171. Stackless Python
Стоит посмотреть этот форк CPython, если идеи
зеленых потоков вам близки
Вкратце - Greenlet на стероидах
Есть шедулер, хвостовая рекурсия,
возможность переезда зеленых потоков между
машинами (почти Erlang/OTP)
Success story - MMORPG Eve Online