6 способов повышения производительности, от использования лучших алгоритмов до использования языка C для многопроцессорной обработки
1. Оптимизация кода и алгоритмов
Всегда внимательно смотрите на свой код и алгоритмы в первую очередь. Многие проблемы со скоростью могут быть решены путем реализации лучшего алгоритма или добавления кэширования. Целые книги написаны на эту тему, но некоторые общие рекомендации, чтобы следовать являются:
- Мера, не угадывай . Измерьте, какие части вашего кода занимают больше всего времени для запуска. Сосредоточьтесь сначала на этих частях.
- Реализовать кэширование . Это может быть большая оптимизация, если вы выполняете много повторных поисков с диска, сети и баз данных.
- Повторно используйте объекты вместо того, чтобы создавать новые на каждой итерации. Python должен очистить каждый созданный вами объект, чтобы освободить память. Это называется сборкой мусора. Сбор мусора из многих неиспользуемых объектов может значительно замедлить работу вашего программного обеспечения.
- Уменьшите количество итераций в коде, если это возможно, и особенно уменьшите количество операций внутри итераций .
- Избегайте (глубокой) рекурсии. Это требует много памяти и домашнего хозяйства для интерпретатора Python. Вместо этого используйте такие вещи, как генераторы и итерации.
- Уменьшите использование памяти. В общем, попробуйте уменьшить использование памяти. Например: разбирайте огромный файл строка за строкой вместо того, чтобы загружать его в память сначала.
- - Не делай этого . Звучит глупо, но вам действительно нужно выполнять эту операцию? Может быть, это будет сделано позже? Или это может быть сделано один раз, и может ли результат этого быть сохранен вместо того, чтобы вычисляться снова и снова?
2. Использование PyPy
Вероятно, вы используете справочную реализацию Python, CPython. Как и большинство людей. Он называется CPython, потому что он написан в C. Если вы уверены, что ваш код привязан к процессору, вам следует изучить PyPy, альтернативу CPython. Это, возможно, быстрое исправление, которое не требует от вас изменения одной строки кода.
PyPy утверждает, что в среднем он в 4,4 раза быстрее, чем CPython . Это делается с помощью метода, называемого just-in-time compilation (JIT) . Java и .NET framework являются другими заметными примерами компиляции JIT. В отличие от этого, CPython использует интерпретацию для выполнения вашего кода. Хотя это обеспечивает большую гибкость, это также очень медленно.
С помощью JIT код компилируется во время выполнения программы. Он сочетает в себе преимущество скорости предварительной компиляции (используется такими языками, как C и C++) с гибкостью интерпретации. Еще одно преимущество заключается в том, что JIT-компилятор может продолжать оптимизировать ваш код во время его выполнения. Чем дольше выполняется ваш код, тем более оптимизированным он станет.
PyPy проделал большой путь за последние несколько лет, и обычно может использоваться в качестве замены drop-in для Python 2 и 3. Он также безупречно работает с такими инструментами, как Pipenv. Дайте ему попробовать!
3. Использование Цитона
Cython предлагает C-подобную производительность с кодом, который написан в основном на Python. Cython позволяет компилировать части вашего кода Python в код C. Таким образом, вы можете конвертировать важные части алгоритма в C, что, как правило, обеспечивает огромный прирост производительности.
Cython является надстройкой языка Python, что означает, что он добавляет дополнительные функции к синтаксису Python. Это не капля в замене, как PyPY. Это требует адаптации к вашему коду и знания дополнительных Cython добавляет к языку.
С Cython также можно воспользоваться преимуществами языка C++, поскольку часть стандартной библиотеки C++ непосредственно импортируется из кода Cython.
Cython особенно популярен среди научных пользователей Python. Несколько примечательных примеров:
- Система компьютерной алгебры SageMath зависит от Cython, как для производительности, так и для взаимодействия с другими библиотеками
- Значительные части библиотек SciPy, pandas и scikit-learn написаны на языке Cython.
- XML toolkit,lxml, написан в основном на языке Cython
4. Использование потоков
Большинство программного обеспечения связано с вводом-выводом и не связано с процессором. В случае, если эти условия являются новыми для вас:
- I / O bound - ваше программное обеспечение в основном ожидает завершения операций ввода-вывода. Это часто происходит при извлечении данных из сети или медленном хранении.
- CPU bound - ваше программное обеспечение выводит процессор. Он использует всю мощность процессора для получения необходимых результатов.
Во время ожидания ответов из сети или с диска можно поддерживать выполнение других частей с помощью нескольких потоков.
Поток-это независимая последовательность выполнения. Ваша программа Python имеет, по умолчанию, один основной поток. Но вы можете создать их больше и позволить Python переключаться между ними. Это переключение происходит так быстро, что кажется, что они работают бок о бок в то же время.отоки-это независимые последовательности выполнения, разделяющие одно и то же пространство памяти.
Но в отличие от других языков, потоки Python не выполняются одновременно — вместо этого они чередуются. Причиной этого является механизм в Python, называемый Global Interpreter Lock (GIL).
Вывод заключается в том, что потоки будут иметь большое значение для программного обеспечения, связанного с вводом/выводом, но бесполезны для программного обеспечения, связанного с процессором.
А почему это так? Все очень просто. Пока один поток ожидает ответа из сети, другие потоки могут продолжать работать. Если вы делаете много сетевых запросов, потоки могут иметь огромное значение. Если ваши потоки вместо этого выполняют тяжелые вычисления, они просто ждут своей очереди, чтобы продолжить. Продевая нитку только ввел бы больше накладных расходов.
5. Использование Asyncio
Asyncio-это относительно новая базовая библиотека в Python. Он решает ту же проблему, что и резьба: он ускоряет программное обеспечение, связанное с вводом/выводом, но делает это по-другому.
Я собираюсь сразу признаться, что я не поклонник asyncio в Python. Это довольно сложно, особенно для начинающих. Еще одна проблема, с которой я столкнулся, заключается в том, что asyncio библиотека сильно изменилась за последние годы. Учебники и примеры кода в интернете часто устаревают. Но это не значит, что он бесполезен. Это мощная парадигма, которая используется во многих высокопроизводительных приложениях. Сайт Real Python имеет хорошее руководство по asyncio, если вам это интересно.
6. Использование сразу нескольких процессоров
Если ваше программное обеспечение привязано к процессору, вы можете часто переписывать свой код таким образом, что вы можете использовать больше процессоров одновременно. Таким образом, вы можете линейно масштабировать скорость выполнения.
Это называется параллелизмом . Не все алгоритмы можно заставить работать параллельно. Например, невозможно просто распараллелить рекурсивный алгоритм. Но почти всегда есть альтернативный алгоритм, который может работать параллельно просто отлично.
Существует два способа использования большего количества процессоров:
- Использование нескольких процессоров и / или ядер на одной машине. В Python это можно сделать с помощью multiprocessing библиотеки.
- Использование сети компьютеров для использования многих процессоров, распределенных по нескольким машинам. Мы называем это распределенными вычислениями.
Эта статья о параллелизме Python фокусируется на способах масштабирования вашего программного обеспечения Python в пределах одной машины. Он также охватывает multiprocessing библиотеку. Если вы решите, что это то, что вам нужно, обязательно проверьте это.
multiprocessing Библиотека, в отличие от threading библиотеки, обходит блокировку глобального интерпретатора Python. Он делает это, фактически порождая несколько экземпляров Python. Таким образом, вместо того, чтобы потоки поочередно выполняли один процесс Python, теперь у вас есть несколько процессов Python, выполняющих ваш код одновременно. визуализированная многопроцессорная обработка,
Многопроцессорная библиотека очень похожа на потоковую библиотеку. Вопрос, который может возникнуть: почему вы даже должны рассматривать резьбу? Ответ можно только догадываться. Потоковая обработка является "более легкой": она требует меньше памяти, так как для нее требуется только один работающий интерпретатор Python. Нерест новых процессов также имеет свои накладные расходы. Таким образом, если ваш код связан с вводом/выводом, потоковая обработка, вероятно, достаточно хороша.
После того, как вы внедрили свое программное обеспечение для работы параллельно, это небольшой шаг вперед, чтобы использовать распределенные вычисления с подобными Hadoop . Используя облачные вычислительные платформы, вы можете масштабироваться с относительной легкостью в эти дни. Вы можете обрабатывать огромные наборы данных в облаке и использовать результаты локально, например. С гибридным способом работы, вы можете сэкономить немного денег, так как вычислительные мощности в облаке довольно дорого.
Заворачивать
Подводить итоги:
- Сначала изучите оптимизацию своих алгоритмов и кода.
- Рассмотрим PyPy, если raw speed может решить ваши проблемы.
- Используйте threading библиотеку и asyncio для программного обеспечения, связанного с вводом-выводом.
- Используйте multiprocessing библиотеку для проблем, связанных с ЦП.
- Если все это еще не достаточно, масштабирование за счет использования облачных вычислительных платформ, таких как Hadoop