3 Совета по использованию функций Python
Язык программирования Python – это язык программирования общего назначения, который можно использовать для различных типов проектов, особенно для машинного обучения, бэкенда и анализа данных.
Написание чистого и понятного кода при одновременном повышении производительности очень важно, особенно если вы используете интерпретируемый язык программирования, как сам Python.
Для повышения производительности есть несколько простых шагов, которые мы можем легко использовать. В этой статье вы узнаете четыре совета functools для написания менее и более эффективного кода.
Что такое модуль Functools?
Functools – это встроенный модуль Python, предоставляющий функции высокого порядка, которые действуют на другие функции или возвращают их, а также операции для collable-объектов.
Декоратор кэша
Использование декоратора кэша очень важно, если вы хотите повысить производительность функции, возвращающей значение, которое вы собираетесь вызывать несколько раз с одними и теми же параметрами.
По сути, декоратор cache запоминает пары параметров и возвращаемых значений. Если вы вызываете функцию с одними и теми же параметрами снова и снова с помощью декоратора кэша, не нужно запускать саму функцию, потому что мы уже знаем выходное значение на основе параметров.
from functools import cache
import time
@cache
def add(x, y):
"""Adds two numbers together."""
print("running")
time.sleep(2)
return x + y
# First two calls
print("NOT CACHED", add(2, 5))
print("CACHED", add(2, 5), "\n")
# Last two calls
print("NOT CACHED", add(6, 5))
print("NOT CACHED", add(3, 5))
Функция add складывает два заданных параметра и возвращает значениеx + y. При первых двух вызовах функция add выполняется один раз, а не два, потому что при первом вызове itcache восстанавливает пару параметров и возвращаемого значения, а поскольку второй вызов функции add имеет те же параметры, что и первый, второй вызов не запускает функцию; вместо этого она напрямую возвращает значение, поскольку оно нам уже известно.
Но при двух последних вызовах функция add запускается дважды, потому что оба вызова имеют параметры, отличные от предыдущих.
Внимание
Будьте осторожны с декоратором кэша, не используйте его, если вам нужно использовать случайное значение в проге.
Кэшированная недвижимость
cached_property – это декоратор, который представляет собой комбинацию кэша и декоратора свойств. Если вы знакомы с другими языками программирования, такими как C# и Java, свойства похожи на геттеры.
Вместо функций мы работаем с классами.
class Numbers:
def __init__(self, *numbers):
self.numbers = numbers
@cached_property
def total(self):
print("Calculating total...")
return sum(self.numbers)
@cached_property
def average(self):
print("Calculating avarage...")
return self.total/len(self.numbers)
m = Numbers(100, 90, 95)
print(m.average)
print(m.average)
print(m.average)
Мы используем функции print в методе total и average, чтобы проверить, работает ли сам метод или нет, и, как вы видите, они работают только один раз, потому что мы уже получили возвращаемое значение.
Предупреждение №2
Но если мы добавим такую строку…
print(m.average) # 95
print(m.average) # 95
m.numbers = (20, 30, 40)
print(m.average) # 95
Как вы видите, последнее m.average возвращает неверное значение (истинное – 30). Это происходит потому, что cached_property просматривает только те параметры, которые мы предоставляем в состоянии построения, а не позже.
Кэш-память LRU
LRU означает наименее недавно использованный. Для тех, кто не знает, что такое мемоизация, декоратор lru_cache мемоизирует сам себя.
Вкратце мы указываем число, которое является максимальным количеством последних вызовов, которые вы хотите вспомнить. Когда мы используем рекурсию, lru_cache может быть полезен в зависимости от задачи.
@lru_cache(maxsize=2)
def fib(n):
if n < 2:
return n
print(f"calculating fib {n}")
return fib(n-1) + fib(n-2)
s = time.time()
[fib(x) for x in range(30)]
print(time.time()-s)
print(fib.cache_info())
Попробуйте этот пример кода с декоратором lru_cache и без него. С ним он работает около 9 секунд, но благодаря силе lru_cache на моей машине он может работать около 0,07 с.
Заключение
В этой статье вы узнали о 3 различных вариациях кэша, которые повысят эффективность вашего кода, если вы будете использовать их правильно.
Вы также узнали, когда не стоит их использовать, чтобы избежать нежелательных возвращаемых значений.