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

Отредактировано

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

10К открытий19К показов

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

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

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

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

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

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

1. List comprehension

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

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

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

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

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

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

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

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

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

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

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

3. NumPy и Pandas

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

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

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

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 и лямбда-функции — и всё это в одну строку, конечно, ускорит код, но прочитать его будет сложно).

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

Следите за новыми постами
Следите за новыми постами по любимым темам
10К открытий19К показов