کش کردن نتایج توابع

  • مدرس : علی بیگدلی
  • تاریخ انتشار: 1404/05/12
  • تعداد بازدید: 17

کش کردن نتایج توابع با functools.cache و functools.lru_cache

گاهی اوقات توابعی داریم که انجام محاسبات سنگین یا تکراری باعث کندی برنامه می‌شود. در این موارد، اگر نتیجه تابع برای ورودی‌های یکسان قبلاً محاسبه شده باشد، می‌توانیم آن نتیجه را ذخیره کنیم و دفعه بعد مستقیماً از آن استفاده کنیم. به این روش کش کردن (caching) می‌گویند. در پایتون با استفاده از ماژول functools، دو ابزار مهم برای کش کردن داریم: cache و lru_cache.

functools.cache چیست؟

تابع cache از پایتون 3.9 به بعد اضافه شده و تمام نتایج محاسبه شده یک تابع را در حافظه ذخیره می‌کند. این یعنی اگر یک بار تابع با یک ورودی اجرا شده باشد، در اجرای بعدی برای همان ورودی، نتیجه بلافاصله بازگردانده می‌شود بدون اجرای دوباره‌ی تابع.

مثال ساده با functools.cache

from functools import cache

@cache
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))  # خروجی: 55

در این مثال:

  • تابع fibonacci به صورت بازگشتی تعریف شده است.
  • با استفاده از @cache، نتایج هر فراخوانی برای مقدار n ذخیره می‌شود.
  • این کار باعث کاهش تعداد محاسبات و افزایش سرعت اجرای تابع می‌شود.

 

functools.lru_cache چیست؟

تابع lru_cache نیز مشابه cache عمل می‌کند، اما یک قابلیت مهم اضافه دارد: فقط تعداد مشخصی از نتایج آخر را در حافظه نگه می‌دارد. وقتی کش پر شود، قدیمی‌ترین نتایج حذف می‌شوند (Least Recently Used یا کم‌استفاده‌ترین). این برای کنترل حافظه بسیار مفید است.

مثال با functools.lru_cache

from functools import lru_cache

@lru_cache(maxsize=3)
def multiply(a, b):
    print(f"Calculating {a} * {b}")
    return a * b

print(multiply(2, 5))  # محاسبه و ذخیره نتیجه
print(multiply(3, 4))  # محاسبه و ذخیره نتیجه
print(multiply(2, 5))  # استفاده از کش (چاپ نمی‌شود)
print(multiply(5, 6))  # محاسبه و ذخیره نتیجه
print(multiply(7, 8))  # محاسبه و ذخیره نتیجه، نتیجه قدیمی حذف می‌شود
print(multiply(3, 4))  # دوباره محاسبه می‌شود چون قبلاً حذف شده

در این مثال:

  • maxsize=3 یعنی فقط 3 نتیجه آخر ذخیره می‌شود.
  • وقتی نتیجه بیش از این مقدار شود، قدیمی‌ترین نتیجه حذف می‌گردد.
  • در مثال، فراخوانی مجدد multiply(3,4) بعد از حذف شدن از کش باعث اجرای دوباره تابع می‌شود.

 

چه زمانی از cache و lru_cache استفاده کنیم؟

  • توابع محاسباتی سنگین که برای ورودی‌های تکراری نتایج مشابه دارند.
  • وقتی حافظه کافی برای نگهداری نتایج داریم و سرعت اجرای برنامه اهمیت دارد.
  • در lru_cache برای کنترل حافظه و جلوگیری از اشغال بیش از حد مناسب است.

 

نکات مهم

  • توابع کش شده باید فقط به ورودی‌هایشان وابسته باشند (بدون حالت‌های جانبی یا تغییر داده‌ها).
  • ورودی‌های تابع باید قابل هش شدن (hashable) باشند، مانند اعداد، رشته‌ها یا تاپل‌ها.
  • در استفاده از کش باید مراقب مصرف حافظه باشیم، مخصوصاً برای داده‌های بزرگ.

 

ثبت دیدگاه


نکته: آدرس ایمیل شما منتشر نخواهد شد

دیدگاه کاربران (0)


هیچ دیدگاهی ثبت نشده است. می‌توانید اولین نفر باشید.