Как стать автором
Обновить

Комментарии 27

Вы забыли написать самое главное — https://lbarman.ch/blog/root-me-pyjail1/:
"You have access to a restricted, sandboxed Python shell (mimicking an online service), and you need to gain broader access to the system. "

Без этой фразы я вообще не мог понять о чем Ваша статья и какую проблему Вы решаете. Помог только Гугл.
Спасибо, дополнил
Не смущает, что по правилам RM публиковать решения плохо? Там вот буквально: «We remind you that publishing solutions on Internet (Youtube, Github, personal blog, ...) is forbidden.»
felix_it Первое, я никого не заставляю полностью повторять своё решение. Второе, одним из основных способов получения новых знаний, как раз является просмотр решений других участников. На RM полагают, что ты либо как хочешь делаешь и в процессе узнаёшь. Либо ты не достоин знать решение.
Я не считаю, что ограничение доступа к информации является лучшем решением.
Ну и третье, пользователи RM не получают за это никакой материальной выгоды, так что моя публикация не наносит никому какого-либо вреда.
Для меня самой большой «интересной особенностью о которой я не догадывался» было наличие Global Interpreter Lock. Почему то во всяких учебниках по python-у этому вопросу почти нигде вообще не удиляют внимания. А в то же время это очень болезненная особенность, существенно ограничивающая применение языка в ряде задач.

Как и где он ограничивает? За 17 лет программирования на Python он меня ни разу не ограничил, и от других не слышал такого тоже.

Ну значит за 17 лет у вас ни разу не было потребности использовать больше 1 ядра эффективно в программе на Python-е.


Пример из моей недавней практики:
python скрипт, который раз в день обходит каталог с архивами с логами от нескольких серверов, парсит их и генерирует некоторые отчеты. Сам процесс анализа данных занимает от силы 30 секунд, но вот загрузка логов — около 10 минут (это бинарные логи в некотором своем формате, дополнительно сжатые gzip-ом, в разжатом виде около 5-6Gb логов на сервер). По скольку все сервера имеют однотипные логи, их более чем хочется загрузить параллельно и потом просто смержить результат, тем более что выполняется все на машине с 18 ядами (Xeon). Но не тут то было, из за global interpreter lock-а, из N python потоков всегда реально выполняется только один, остальные ждут возможности захватить GIL. Так что итоговая производительность загрузки при многопоточном подходе получается не в N раз быстрее, а раза вы полтора медленнее.


Если подытожить — то cpython реализация не позволяет эффективно использовать несколько потоков, вообще никак.

А multiprocessing модуль не пробовали?

Если честно, я очень скептически отношусь к передаче большого количества DataFrame-ов, каждый порядка 500Мб в памяти, через pipe-а из дочерних процессов. Но попробую.

А зачем датафреймы-то передавать? Сразу используйте разделяемую память, а лучше анализируйте отдельно друг от друга в разных потоках / процессах.
Многие функции pandasа однопоточны. Так что, собрав все в один большой датафрейм, вы многократно замедлите обработку.

Анализировать отдельно — это будет не так тривиально, т.к. код усыпан всякими groupby, делать их на отдельных маленьких DataFrame-ах а потом мержить вместе — только багов насажаешь.
А в разделяемую память класть — это нужно ведь будет ручками каждый отдельный столбец оформлять (а их там штук 50), а потом обратно собирать в дата-фрейм, что бы можно было анализировать при помощи pandas.


P.S.а вообще я попробовал, решение "в лоб" через pool.map приводит к тому, что около 5% времени уходит на передачу данных меж процессами. Не так ужасно, я думал будет хуже.


В любом случае — отсутствие нормальных потоков — это ограничивающий фактор. Тот же numpy по этой причине изворачивается с созданием нативных потоков, для параллельной обработки.

Ну с таким подходом можно и про xargs -P вспомнить. Действительно, при чем тут язык.

А про ограничение (архитектурное, замечу) языка стоит знать. Треды в языке вроде как есть. Но никто не задумывается, что в единицу времени будет выполняться ровно один тред. Мне кажется, это слишком интересная особенность чтобы о ней молчать.

Не понимаю, за что qrck13 заминусовали.
Не понимаю, за что qrck13 заминусовали.


Думаю, что минусы в основном за:

интересной особенностью о которой я не догадывался
и
нигде вообще не удиляют внимания
Но никто не задумывается, что в единицу времени будет выполняться ровно один тред.

Если вы для себя Питон только что открыли, то да, никто не задумывается и все молчат :) А вообще, про этот GIL уже столько статей написано, столько копей поломано, что фактически нет смысла обсуждать…
> Если вы для себя Питон только что открыли, то да, никто не задумывается и все молчат :) А вообще, про этот GIL уже столько статей написано, столько копей поломано, что фактически нет смысла обсуждать…

У меня на работе мы в команде используем python как вспомогательный скриптовый язык (в основном для анализа данных при отладке основных проектов), основная разработка на C++/C#. Т.е. никто не изучал python на таком глубоком уровне. Но стандартный «common sense» на основании опыта с другими языками (у некоторых из команды — больше 20 лет опыта) никак не наводит на мысль, что в каком-то из языков может быть засада с такой базовой и основопологающей вещью как потоки. Когда я об этом «открытии» рассказал коллегам — сюрприз был у всех.
Вот это эпик!!! Для io-bound задач нужно и инструмент подбирать соответствующий, twisted там или tornado. Но да, виноват во всем Python, а не человек!

PS: Ему не multiprocessing нужен, раз bottleneck в загрузке, а не парсинге.

Эпик, это кричать не разобравшись в вопросе.


Это не io-bound задача, на io там уходит меньше 15% времени, т.к. логи очень хорошо пожаты.

Во-первых, для парсинга логов отлично подойдет multiprocessing, который распараллелит задачу на несколько процессоров.


Во-вторых, ввод-вывод хорошо ускоряется с помощью async / await.


В-третьих, GIL при необходимости можно легко разблокировать с помощью cython или numba.

GIL при необходимости можно легко разблокировать с помощью cython

Но это уже будет не совсем python, хоть и запускаться процесс будет из python.
По тому же принципу можно просто через system запускать другие процессы (скрипты на python) в бекграунде и говорить, что GIL совершенно ничем никому не мешает :)

Чем cython не питон?

Можно использовать PyPy, например или другие альтернативные реализации без GIL
Довольно интересное применение Python
НЛО прилетело и опубликовало эту надпись здесь
Для таких вещей во-первых хочется использовать import (который нельзя переопределить и который восстанавливает вменяемость некоторых переменных), во-вторых dir() (если его не переопределили), в третьих — хардкорную интроспекцию (import inspect).
Типичное приветствие новичка хабрасообществом, ахах) ничего нового: куча минусусов новичку, за попытку написания интересного материала.
Публиковать решения в готовом виде не стоит, конечно, особенно, когда авторы задач просят этого не делать. Ещё как минимум стоило убрать их под спойлер, вы же лишаете людей удовольствия!

Лучше бы статью про root-me небольшую написали, за наводку на сайт спасибо.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории