الفرق بين المراجعتين لصفحة: «Python/functools/lru cache»
إضافة الصّفحة |
لا ملخص تعديل |
||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:الدالة <code>functools.lru_cache()</code> في بايثون}}</noinclude> | <noinclude>{{DISPLAYTITLE:الدالة <code>functools.lru_cache()</code> في بايثون}}</noinclude> | ||
الدّالة <code>functools.lru_cache()</code> مُزخرفٌ يُحيط دالّة بكائن قابل للاستدعاء مُتذكّر (memoizing callable). | الدّالة <code>functools.lru_cache()</code> [https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D9%85%D8%B2%D8%AE%D8%B1%D9%81%D8%A7%D8%AA-decorators-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r303/ مُزخرفٌ] يُحيط دالّة بكائن قابل للاستدعاء مُتذكّر (memoizing callable). | ||
الكائن المُتذكِّر يحتفظ بعددٍ من آخر الاستدعاءات حسب قيمة المُعامل <code>maxsize</code>. ويُمكن أن تختصر الوقت إن كانت دالّة تأخذ الكثير من الوقت تُستدعَى بنفس المُعاملات عدّة مرّات. | الكائن المُتذكِّر يحتفظ بعددٍ من آخر الاستدعاءات حسب قيمة المُعامل <code>maxsize</code>. ويُمكن أن تختصر الوقت إن كانت دالّة تأخذ الكثير من الوقت تُستدعَى بنفس المُعاملات عدّة مرّات. | ||
سطر 18: | سطر 18: | ||
مُعامل يُحدّد ما إذا كانت مُعاملات الدّالة التي تكون أنواعها مُختلفةً ستُخبأ بشكل مُنفصل أو لا. | مُعامل يُحدّد ما إذا كانت مُعاملات الدّالة التي تكون أنواعها مُختلفةً ستُخبأ بشكل مُنفصل أو لا. | ||
إن كانت قيمته القيمةَ | إن كانت قيمته القيمةَ <code>True</code>، فستُخبّأ مُعاملات كلّ نوع على حدة. فمثلًا، سيُعامل <code>f(3)</code> و<code>f(3.0)</code> على أنّهما استدعاءان مُختلفان مع نتيجتين مُختلفتين. | ||
القيمة الافتراضيّة هي القيمة False. | القيمة الافتراضيّة هي القيمة <code>False</code>. | ||
== أمثلة == | == أمثلة == | ||
سطر 43: | سطر 43: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
مثال على طريقة فعّالة لحساب أعداد فيبوناتشي باستخدام تخبئة لتطبيق تقنيّة برمجة ديناميكيّة: | مثال على طريقة فعّالة لحساب [https://ar.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF_%D9%81%D9%8A%D8%A8%D9%88%D9%86%D8%A7%D8%AA%D8%B4%D9%8A أعداد فيبوناتشي] باستخدام تخبئة لتطبيق تقنيّة برمجة ديناميكيّة: | ||
<syntaxhighlight lang="python3"> | <syntaxhighlight lang="python3"> | ||
@lru_cache(maxsize=None) | @lru_cache(maxsize=None) | ||
سطر 59: | سطر 59: | ||
== ملاحظات == | == ملاحظات == | ||
للمُساعدة على قياس مدى كفاءة التّخبئة وتغيير قيمة المُعامل <code>maxsize</code>، تحصل الدّالة المُزخرَفة على الدّالة <code>cache_info()</code> التي تُعيد صفًّا مُسمًّى يُظهر الضّربات (<code>hits</code>)، حالات الفشل (<code>misses</code>)، عدد الاستدعاءات الأقصى (<code>maxsize</code>)، وعدد الاستدعاءات الحاليّ (<code>maxsize</code>). تكون الضّربات وحالات الفشل | للمُساعدة على قياس مدى كفاءة التّخبئة وتغيير قيمة المُعامل <code>maxsize</code>، تحصل الدّالة المُزخرَفة على الدّالة <code>cache_info()</code> التي تُعيد صفًّا مُسمًّى يُظهر الضّربات (<code>hits</code>)، حالات الفشل (<code>misses</code>)، عدد الاستدعاءات الأقصى (<code>maxsize</code>)، وعدد الاستدعاءات الحاليّ (<code>maxsize</code>). تكون الضّربات وحالات الفشل تقريبيّة في بيئة مُتعدّدة السّلاسل (multi-threaded environment). | ||
يُوفّر المُزخرِف كذلك دالّة <code>cache_clear()</code> لمسح أو تعطيل صلاحيّة التّخبئة. | يُوفّر المُزخرِف كذلك دالّة <code>cache_clear()</code> لمسح أو تعطيل صلاحيّة التّخبئة. |
مراجعة 16:05، 20 يونيو 2018
الدّالة functools.lru_cache()
مُزخرفٌ يُحيط دالّة بكائن قابل للاستدعاء مُتذكّر (memoizing callable).
الكائن المُتذكِّر يحتفظ بعددٍ من آخر الاستدعاءات حسب قيمة المُعامل maxsize
. ويُمكن أن تختصر الوقت إن كانت دالّة تأخذ الكثير من الوقت تُستدعَى بنفس المُعاملات عدّة مرّات.
ولأنّ النّتائج تُخبّأ (cache) في قاموس، فيجب على المُعاملات المُمرّرة للدّالة المُزخرَفة أن تكون قابلة للتّجزئة (hashable).
البنية العامة
@functools.lru_cache(maxsize=128, typed=False)
المعاملات
maxsize
عدد الاستدعاءات التي ستُخبّأ، إن مُرّرت له القيمة None
، تُعطّل ميّزة LRU (الأقلّ استخدامًا مؤخّرًا، Least recently used) ويُمكن للتّخبئة أن تنمو دون قيود. تعمل ميّزة LRU بشكل أفضل إن كانت قيمة maxsize
قوّة 2 (power-of-two).
typed
مُعامل يُحدّد ما إذا كانت مُعاملات الدّالة التي تكون أنواعها مُختلفةً ستُخبأ بشكل مُنفصل أو لا.
إن كانت قيمته القيمةَ True
، فستُخبّأ مُعاملات كلّ نوع على حدة. فمثلًا، سيُعامل f(3)
وf(3.0)
على أنّهما استدعاءان مُختلفان مع نتيجتين مُختلفتين.
القيمة الافتراضيّة هي القيمة False
.
أمثلة
المثال التّالي يوضّح كيفيّة عمل هذه الدّالة للحصول على محتوى ويب ثابت:
@lru_cache(maxsize=32)
def get_pep(num):
'الحصول على نصّ من اقتراح من اقتراحات تحسين بايثون'
resource = 'http://www.python.org/dev/peps/pep-%04d/' % num
try:
with urllib.request.urlopen(resource) as s:
return s.read()
except urllib.error.HTTPError:
return 'Not Found'
>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
... pep = get_pep(n)
... print(n, len(pep))
>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
مثال على طريقة فعّالة لحساب أعداد فيبوناتشي باستخدام تخبئة لتطبيق تقنيّة برمجة ديناميكيّة:
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
ملاحظات
للمُساعدة على قياس مدى كفاءة التّخبئة وتغيير قيمة المُعامل maxsize
، تحصل الدّالة المُزخرَفة على الدّالة cache_info()
التي تُعيد صفًّا مُسمًّى يُظهر الضّربات (hits
)، حالات الفشل (misses
)، عدد الاستدعاءات الأقصى (maxsize
)، وعدد الاستدعاءات الحاليّ (maxsize
). تكون الضّربات وحالات الفشل تقريبيّة في بيئة مُتعدّدة السّلاسل (multi-threaded environment).
يُوفّر المُزخرِف كذلك دالّة cache_clear()
لمسح أو تعطيل صلاحيّة التّخبئة.
يُمكن الوصول إلى الدّالة الأصليّة عبر الخاصيّة __wrapped__
. هذا مُفيد لفحص الدّالة، أو تجاهل التّخبئة، أو لإعادة زخرفة الدّالة بتخبئة مُختلفة.
تعمل تخبئة LRU بشكل أفضل عندما تتوقّع آخر الاستدعاءاتِ حدوثًا الاستدعاءات القادمة (فمثلًا، تتغيّر أكثر المقالات شهرةً في خادوم أخبارٍ كلّ يوم). الحدّ الأقصى لحجم الخبيئة يتحقّق من أنّ التّخبئة لا تنمو دون ارتباط على عمليّات تأخذ وقتًا طويلًا لتتم، كخوادم الويب مثلًا.