3 простых способа ускорить код на Python
Если вы разрабатываете на Python, наверняка задумывались о том, как ускорить код. В статье разбираем три способа, которые помогут в этом.
10К открытий19К показов
Всем добрый день, меня зовут Даниил, я backend-разработчик из департамента IT Kokoc Group.
Даниил Громов
Backend-разработчик в департаменте IT Kokoc Group
Python — это мощный и гибкий язык программирования. Однако из-за динамической типизации и интерпретируемости его производительность оставляет желать лучшего. И наверное, каждый, кто разрабатывает на нём продолжительное время, задавался вопросом, как ускорить код на Python. В этой статье рассмотрим три способа на примере одного кейса.
Кейс для ускорения кода на Python
Рассмотрим простую функцию, которая вычисляет сумму квадратов элементов большого списка чисел.
А теперь применим техники ускорения кода и понаблюдаем, как каждая из них отразится на скорости выполнения программы.
1. List comprehension
List comprehension — эффективный способ создавать и обрабатывать списки в одной строке. В Python он работает быстрее, чем традиционный цикл for
, потому что весь процесс в нём оптимизирован и протекает внутри интерпретатора.
List comprehensions обычно вызывают меньше методов, чем for. Второй для каждой итерации вызывает метод append, что создаёт дополнительную нагрузку и обновляет состояние переменной на каждой итерации. А list comprehension создаёт новый список сразу, такой подход может быть более эффективным.
Важно отметить, что, хотя list comprehension обычно быстрее, его не всегда следует использовать. Если вы пытаетесь сделать что-то сложнее обычного преобразования данных, он может быть тяжеловат для понимания. Ясный и читаемый цикл for
может быть лучшим выбором.
2. Map() и lambda-функции
map()
— встроенная функция, которая всегда используется в комбинации с итерируемой последовательностью, в данном случае со списком. Она идёт по каждому элементу последовательности (то есть к каждому объекту из списка) и применяет к нему функцию, которую приняла первым позиционным аргументом.
map()
реализована на более быстром Си. И, как и list comprehension, оптимизирована на уровне интерпретатора Python. То есть при её использовании вы также передаёте всю работу интерпретатору, который оптимизирует выполнение операции.
Кроме того, map()
в Python возвращает итератор, а не список. А итераторы — более эффективный способ обработки больших объёмов данных. Они не требуют загрузки всего набора данных в память сразу, а генерируют каждый элемент по мере необходимости. Это значительно снижает потребление памяти, особенно при работе с большими наборами данных.
Это также связано с принципом «ленивого вычисления»: итератор, возвращённый функцией map(), вычисляет каждый элемент «на лету» и только при необходимости.
Lambda-функции в Python — это анонимные функции, которые можно определить прямо в месте использования. То есть вместо того чтобы задавать отдельную именованную функцию через def
, можно написать короткую лямбду — прямо в вызове map()
.
3. NumPy и Pandas
NumPy — это мощная библиотека, которая предоставляет объекты массивов N-мерного массива с эффективными операциями. При работе с большими массивами данных NumPy может быть намного эффективнее стандартных списков Python благодаря оптимизированным и векторизованным операциям.
Pandas — библиотека, предоставляющая эффективные структуры данных и инструменты анализа данных.
Фактически это надстройка над NumPy. Так что для ускорения кода логично использовать ту библиотеку, которая уже инсталлирована в проекте.
В основном NumPy и Pandas используют для работы с таблицами, когда нужно, допустим, выгрузить Excel-таблицу или рассортировать ячейки. Другие сферы — компьютерное зрение, векторная геометрия и так далее.
Код, в котором используют NumPy и Pandas, часто работает быстрее, чем аналогичный, но написанный с использованием стандартных функций и структур данных Python. И вот по каким причинам:
- Большая часть библиотек NumPy и Pandas написана на Cи и C++. Благодаря этому скорость выполнения выше.
- Векторизованные операции выполняются сразу над массивами данных, а не поэлементно. Это обеспечивает значительное увеличение производительности, особенно при работе с большими объёмами данных.
- Эффективное использование памяти. NumPy и Pandas используют эффективные структуры данных, которые занимают меньше памяти и позволяют выполнять операции быстрее.
- Функции оптимизированы для быстрого выполнения на больших объёмах данных.
Результаты
Время выполнения каждого подхода будет зависеть от машины и конкретного случая, но ориентировочно можно представить следующие результаты:
- стандартный подход: 0.25 секунды;
- map и lambda: 0.18 секунды;
- list comprehension: 0.17 секунды;
- NumPy: 0.006 секунды;
- Pandas: 0.006 секунды.
Как видно, оптимизация может значительно ускорить код на Python. Однако не стоит забывать, что оптимальность любого подхода зависит от конкретного случая, и не всегда нужно стремиться к максимальной скорости исполнения в ущерб читаемости и поддерживаемости (list comprehension, внутри которого ещё два list comprehension, map и лямбда-функции — и всё это в одну строку, конечно, ускорит код, но прочитать его будет сложно).
В большинстве случаев выбор должен основываться на том, какой вариант делает код более понятным и поддерживаемым.
10К открытий19К показов