Небольшое изменение стиля и Python становится молниеносным
Python быстрый
Советы по ускорению работы кода Python
Эта статья направлена на то, чтобы выделить быстрые победы, которые полезны для всех, кто хочет повысить производительность своего кода на Python.
1. Удалите избыточный код.
- Очевидно, что самая важная задача - сначала написать чистый и эффективный код. Мы должны убедиться, что код не выполняет одни и те же вычисления в цикле снова и снова.
- Также важно не открывать / закрывать соединения ввода-вывода для каждой записи в коллекции.
- Проанализируйте, можно ли кэшировать объекты.
- Убедитесь, что вы не создаете новые экземпляры объектов, когда они не требуются.
- Кроме того, убедитесь, что ваш код не выполняет повторяющиеся идентичные вычислительно ресурсоемкие задачи и написан лаконично.
После того, как чистый код будет реализован, следуйте этим советам, которые были изложены ниже.
2. Используйте структуры данных на основе хеш-таблиц.
- Если ваше приложение будет выполнять большое количество операций поиска по большой коллекции элементов и у вас нет дубликатов в ваших элементах, используйте словарь.
- Это высокопроизводительный сбор данных.
- Операция стоит O (1), чтобы найти предмет.
- Сказав это, вероятно, это будет неэффективно, если в вашей коллекции не так много предметов.
Вместо того:
items = ['a', 'b',..,'100m'] #1000s of items found = False for i in items: if (i == '100m'): found = True
Do:
items = {'a':'a', 'b':'b:,..,'100m':'100m'} #each item is key/value
found = False
if '100m' in items:
found = True
Используйте поисковые запросы, если можете, вместо того, чтобы перебирать коллекции
3. Используйте матричную векторизацию вместо циклов
Попробуйте использовать библиотеки Python, построенные на C, такие как Numpy, Scipy и Pandas, и воспользуйтесь преимуществами векторизации. Вместо написания цикла, который обрабатывает один элемент в массиве M количество раз, он может обрабатывать элементы одновременно. Векторизация часто включает в себя оптимизированную стратегию сегментирования.
import numpy as np
array = np.array([[1., 2., 3.], [4., 5., 6.]])
m_array = array*array
4. Уменьшите количество строк в коде.
Используйте встроенные функции Python, такие как map ()
Вместо того:
newlist = []
def my_fun(a):
return a + 't'
for w in some_list:
newlist.append(my_fun(w))
Do:
def my_fun(a): return a + 't' newlist = map(my_fun, some_list)
При обновлении строковой переменной каждый раз создается новый экземпляр
Вместо того:
my_var = 'Malik' myname_blog = 'Farhad ' + my_var + ' FinTechExplained'
Do:
my_var = 'Malik'
myname_blog = 'Farhad {0} FinTechExplained'.format(my_var)
Приведенный выше стиль сократит объем памяти.
Используйте понимание цикла, чтобы уменьшить количество строк
Вместо того:
for x in big_x:
for y in x.Y:
items.append(x.A + y.A)
Do:
items = [x.A+y.A for x in big_x for y in x.Y]
5. Используйте многопроцессорность
Если ваш компьютер имеет более одного ядра, попробуйте использовать многопроцессорность в Python.
Многопроцессорность позволяет распараллеливать ваш код. Многопроцессорность является дорогостоящей, поскольку вы собираетесь создавать экземпляры новых процессов, получать доступ к общей памяти и т. Д., Поэтому используйте многопроцессорность только в том случае, если есть достаточно большие данные, которые вы можете разделить. Для очень небольшого количества данных использование многопроцессорной обработки не всегда стоит усилий.
Вместо того
def some_func(d): #computations data = [1,2,..,10000] #large data for d in data: some_func(d)
Do
import multiprocessing def some_func(d): #computations data = [1,2,..,10000] #large data pool = multiprocessing.Pool(processes=number_of_processors) r = pool.map(some_func, data) pool.close()
Многопроцессорность - самый важный фактор, поскольку я одновременно выполняю несколько путей выполнения.
6. Используйте Cython
Cython - это статический компилятор, который может оптимизировать ваш код за вас.
Загрузите расширения cypthonmagic и используйте тег cython для компиляции кода с помощью cython.
Используйте Pip для установки Cython:
pip install Cython
Чтобы использовать Cython:
%load_ext cythonmagic
%%cython
def do_work():
... #computationally intensive work
7. Не используйте Excel, если вам это не нужно
Недавно реализовывал приложение. Мне потребовалось больше времени для загрузки и сохранения данных в / из файлов Excel. Вместо этого я выбрал путь создания нескольких файлов CSV и создал папку для группировки файлов.
Примечание. Это зависит от вашего варианта использования. Возможно, вы можете создать несколько файлов CSV и просто использовать утилиту на родном языке, которая может объединить несколько файлов CSV в файл Excel, если создание Excel является узким местом.
Вместо того:
df = pd.DataFrame([['a', 'b'], ['c', 'd']],index=['row 1', 'row 2'],columns=['col 1', 'col 2'])
df.to_excel("my.xlsx")
df2 = df.copy()
with pd.ExcelWriter('my.xlsx') as writer:
df.to_excel(writer, sheet_name='Sheet_name_1')
df2.to_excel(writer, sheet_name='Sheet_name_2')
Do:
df = pd.DataFrame([['a', 'b'], ['c', 'd']],index=['row 1', 'row 2'],columns=['col 1', 'col 2'])
df2 = df.copy()
df.to_csv("my.csv")
df2.to_csv("my.csv")
8. Используйте Numba.
Это JIT-компилятор. С помощью декораторов Numba компилирует аннотированный код Python и NumPy в LLVM.
Разделите функцию на две части:
1. Функция, которая выполняет вычисления - украсить с помощью @autojit
2. Функция, выполняющая ввод-вывод
from numba import jit, autojit
@autojit
def calculation(a):
....
def main():
calc_result = calculation(some_object)
d = np.array(calc_result)
#save to file
return d
9. Используйте Dask для распараллеливания операций Pandas DataFrame.
Даск отличный! Это помогло мне обрабатывать числовые функции в фреймах данных и numpy параллельно. Я даже попытался масштабировать его на кластере, и это было так просто!
import pandas as pd import dask.dataframe as dd from dask.multiprocessing import getdata = pd.DataFrame(...) #large data setdef my_time_consuming_function(d): .... #long running functionddata = dd.from_pandas(data, npartitions=30)def apply_my_func(df): return df.apply( (lambda row: my_time_consuming_function(*row)), axis=1)def dask_apply(): return ddata.map_partitions(apply_my_func).compute(get=get)
10. Используйте пакет swifter.
Swifter использует Dask в фоновом режиме. Он автоматически определяет наиболее эффективный способ распараллеливания функции во фрейме данных.
Это плагин для Pandas.
import swifter import pandas as pda_large_data_frame = pd.DataFrame(...) #large data set def my_time_consuming_function(data): ...result = a_large_data_frame.swifter.apply(some_function)
11. Используйте пакет Pandarallel.
Pandarallel может распараллеливать операции pandas над несколькими процессами.
Опять же, используйте только в том случае, если у вас большой набор данных.
from pandarallel import pandarallel from math import sinpandarallel.initialize()# ALLOWED def my_time_consuming_function(x): ....df.parallel_apply(my_time_consuming_function, axis=1)
Резюме
Цель этой статьи - кратко осветить ключевые советы по повышению производительности.
Надеюсь, это поможет