Логотип компании Kokoc Group
Kokoc Group

3 простых способа ускорить код на Python

Если вы разрабатываете на Python, наверняка задумывались о том, как ускорить код. В статье разбираем три способа, которые помогут в этом.

4576

Всем добрый день, меня зовут Даниил, я backend-разработчик из департамента IT Kokoc Group.

Python — это мощный и гибкий язык программирования. Однако из-за динамической типизации и интерпретируемости его производительность оставляет желать лучшего. И наверное, каждый, кто разрабатывает на нём продолжительное время, задавался вопросом, как ускорить код на Python. В этой статье рассмотрим три способа на примере одного кейса.

Кейс для ускорения кода на Python

Рассмотрим простую функцию, которая вычисляет сумму квадратов элементов большого списка чисел.

как ускорить код на python
В этом примере мы используем стандартный подход с помощью встроенной функции sum и генератора списка

А теперь применим техники ускорения кода и понаблюдаем, как каждая из них отразится на скорости выполнения программы.

1. List comprehension

python list comprehension

List comprehension — эффективный способ создавать и обрабатывать списки в одной строке. В Python он работает быстрее, чем традиционный цикл for, потому что весь процесс в нём оптимизирован и протекает внутри интерпретатора.

List comprehensions обычно вызывают меньше методов, чем for. Второй для каждой итерации вызывает метод append, что создаёт дополнительную нагрузку и обновляет состояние переменной на каждой итерации. А list comprehension создаёт новый список сразу, такой подход может быть более эффективным.

Важно отметить, что, хотя list comprehension обычно быстрее, его не всегда следует использовать. Если вы пытаетесь сделать что-то сложнее обычного преобразования данных, он может быть тяжеловат для понимания. Ясный и читаемый цикл for может быть лучшим выбором.

2. Map() и lambda-функции

как ускорить код на python

map() — встроенная функция, которая всегда используется в комбинации с итерируемой последовательностью, в данном случае со списком. Она идёт по каждому элементу последовательности (то есть к каждому объекту из списка) и применяет к нему функцию, которую приняла первым позиционным аргументом.

map() реализована на более быстром Си. И, как и list comprehension, оптимизирована на уровне интерпретатора Python. То есть при её использовании вы также передаёте всю работу интерпретатору, который оптимизирует выполнение операции.

Кроме того, map() в Python возвращает итератор, а не список. А итераторы — более эффективный способ обработки больших объёмов данных. Они не требуют загрузки всего набора данных в память сразу, а генерируют каждый элемент по мере необходимости. Это значительно снижает потребление памяти, особенно при работе с большими наборами данных.

Это также связано с принципом «ленивого вычисления»: итератор, возвращённый функцией map(), вычисляет каждый элемент «на лету» и только при необходимости.

Lambda-функции в Python — это анонимные функции, которые можно определить прямо в месте использования. То есть вместо того чтобы задавать отдельную именованную функцию через def, можно написать короткую лямбду — прямо в вызове map().

3. NumPy и Pandas

как ускорить код на python

NumPy — это мощная библиотека, которая предоставляет объекты массивов N-мерного массива с эффективными операциями. При работе с большими массивами данных NumPy может быть намного эффективнее стандартных списков Python благодаря оптимизированным и векторизованным операциям.

как ускорить код на python

Pandas — библиотека, предоставляющая эффективные структуры данных и инструменты анализа данных.

Фактически это надстройка над NumPy. Так что для ускорения кода логично использовать ту библиотеку, которая уже инсталлирована в проекте.

В основном NumPy и Pandas используют для работы с таблицами, когда нужно, допустим, выгрузить Excel-таблицу или рассортировать ячейки. Другие сферы — компьютерное зрение, векторная геометрия и так далее.

Код, в котором используют NumPy и Pandas, часто работает быстрее, чем аналогичный, но написанный с использованием стандартных функций и структур данных Python. И вот по каким причинам:

  1. Большая часть библиотек NumPy и Pandas написана на Cи и C++. Благодаря этому скорость выполнения выше.
  2. Векторизованные операции выполняются сразу над массивами данных, а не поэлементно. Это обеспечивает значительное увеличение производительности, особенно при работе с большими объёмами данных.
  3. Эффективное использование памяти. NumPy и Pandas используют эффективные структуры данных, которые занимают меньше памяти и позволяют выполнять операции быстрее.
  4. Функции оптимизированы для быстрого выполнения на больших объёмах данных.

Результаты

Время выполнения каждого подхода будет зависеть от машины и конкретного случая, но ориентировочно можно представить следующие результаты:

  • стандартный подход: 0.25 секунды;
  • map и lambda: 0.18 секунды;
  • list comprehension: 0.17 секунды;
  • NumPy: 0.006 секунды;
  • Pandas: 0.006 секунды.

Как видно, оптимизация может значительно ускорить код на Python. Однако не стоит забывать, что оптимальность любого подхода зависит от конкретного случая, и не всегда нужно стремиться к максимальной скорости исполнения в ущерб читаемости и поддерживаемости (list comprehension, внутри которого ещё два list comprehension, map и лямбда-функции — и всё это в одну строку, конечно, ускорит код, но прочитать его будет сложно).

В большинстве случаев выбор должен основываться на том, какой вариант делает код более понятным и поддерживаемым.

4576