Источник: Nuances of Programming
Как я сократил время выполнения приложения на 1/10
Данные советы просты в реализации и могут пригодиться вам в обозримом будущем.
Считается, что первоочередной задачей программиста является написание чистого и эффективного кода. Как только вы создали чистый код, можете переходить к следующим 10 подсказкам. Я подробно объясню их ниже.
Как я измеряю время и сложность кода?
Я пользуюсь Python профайлером, который измеряет пространственную и временную сложность программы. Вести журнал производительности можно через передачу дополнительного файла вывода с помощью параметра -о.
python -m cProfile [-o output_file] my_python_file.py
Используйте структуры данных из хеш-таблиц
- Если ваше приложение будет выполнять огромное количество операций поиска на большой коллекции неповторяющихся элементов, то воспользуйтесь словарем.
- Это высокопроизводительная коллекция данных.
- Сложность поиска элемента — O(1).
- Здесь стоит упомянуть, что словари не эффективны для наборов данных с малым количеством элементов.
Вместо:
Если есть такая возможность, то вместо перебора данных коллекций пользуйтесь поиском.
Векторизация вместо циклов
Присмотритесь к Python-библиотекам, созданным на С (Numpy, Scipy и Pandas), и оцените преимущества векторизации. Вместо прописывания цикла, который раз за разом обрабатывает по одному элементу массива М, можно выполнять обработку элементов одновременно. Векторизация часто включает в себя оптимизированную стратегию группировки.
import numpy as np
array = np.array([[1., 2., 3.], [4., 5., 6.]])
m_array = array*array
Сократите количество строк в коде
Пользуйтесь встроенными функциями Python. Например, map()
Вместо:
Каждое обновление строковой переменной создает новый экземпляр
Вместо:
my_var = ‘Malik’
myname_blog = ‘Farhad ‘ + my_var + ‘ FinTechExplained’
Пишите:
my_var = ‘Malik’
myname_blog = ‘Farhad {0} FinTechExplained’.format(my_var)
Пример выше уменьшает объем памяти.
Для сокращения строк пользуйтесь циклами и генераторами for
вместо
Пользуйтесь многопроцессорной обработкой
Если ваш компьютер выполняет более одного процесса, тогда присмотритесь к многопроцессорной обработке в Python.
Она разрешает распараллеливание в коде. Многопроцессорная обработка весьма затратна, поскольку вам придется инициировать новые процессы, обращаться к общей памяти и т.д., поэтому пользуйтесь ей только для большого количества разделяемых данных. Для небольших объемов данных многопроцессорная обработка не всегда оправдана.
Многопроцессорная обработка очень важна для меня, поскольку я обрабатываю по несколько путей выполнения одновременно.
Пользуйтесь Cython
Cython — это статический компилятор, который будет оптимизировать код за вас.
Загрузите расширения Cythonmagic и пользуйтесь тегом Cython для компиляции кода через Cython.
Воспользуйтесь Pip для установки Cython:
pip install Cython
Для работы с Cython:
%load_ext cythonmagic
%%cython
def do_work():
… #работа с большим объемом вычислений
Пользуйтесь Excel только при необходимости
Не так давно мне нужно было реализовать одно приложение. И мне бы пришлось потратить много времени на загрузку и сохранение файлов из/в Excel. Вместо этого я пошел другим путем: создал несколько CSV-файлов и сгруппировал их в отдельной папке.
Примечание: все зависит от задачи. Если создание файлов в Excel сильно тормозит работу, то можно ограничиться несколькими CSV-файлами и утилитой на нативном языке, которая объединит эти CSV в один Excel-файл.
Пользуйтесь Numba
Это — JIT-компилятор (компилятор «на лету»). С помощью декоратора Numba компилирует аннотированный Python- и NumPy-код в LLVM.
Разделите функцию на две части:
1. Функция, которая выполняет вычисления. Ее декорируйте с @autojit.
2. Функция, которая выполняет операции ввода-вывода.
Пользуйтесь Dask для распараллеливания операций Pandas DataFrame
Dask очень классный! Он помог мне с параллельной обработкой множества функций в DataFrame и NumPy. Я даже попытался масштабировать их в кластере, и все оказалось предельно просто!
Пользуйтесь пакетом swifter
Swifter использует Dask в фоновом режиме. Он автоматически рассчитывает наиболее эффективный способ для распараллеливания функции в пакете данных.
Это плагин для Pandas.
Пользуйтесь пакетом Pandarallel
Pandarallel может распараллеливать операции на несколько процессов.
Опять же, подходит только для больших наборов данных.
Общие советы
- Первым делом нужно писать чистый и эффективный код. Мы должны проследить, чтобы код внутри цикла не выполнял одни и те же вычисления.
- Также важно не открывать/закрывать подключения ввода-вывода для каждой записи в коллекции.
- Подумайте, можно ли кэшировать объекты.
- Проверьте, что не создаете новые экземпляры объектов там, где они не нужны.
- И, наконец, убедитесь, что код написан лаконично и не выполняет одни и те же повторяющиеся задачи со сложными вычислениями.
Как только вы добились чистого кода, можно приступать к рекомендациям, описанным выше.
Заключение
В данной статье были даны краткие подсказки по написанию кода. Они будут весьма полезны для тех, кто хочет улучшить производительность Python-кода.
Читайте также:
Читайте нас в телеграмме и vk
Перевод статьи Farhad Malik: How To Make Python Faster