التخزين المؤقت
في مجال الحوسبة ، تُعدّ تقنية التخزين المؤقت ( memoization) أسلوبًا لتحسين الأداء ، يُستخدم أساسًا لتسريع برامج الحاسوب . وتعمل هذه التقنية عن طريق تخزين نتائج الاستدعاءات المكلفة للدوال البحتة ، بحيث يمكن استرجاع هذه النتائج بسرعة في حال تكرار نفس المدخلات. وهي نوع من أنواع التخزين المؤقت ، تُنفّذ عادةً باستخدام جدول تجزئة ، وتُعدّ مثالًا نموذجيًا على المفاضلة بين المساحة والوقت ، حيث يتم تقليل وقت تشغيل البرنامج بزيادة استهلاكه للذاكرة. يمكن تطبيق تقنية التخزين المؤقت في أي لغة برمجة، مع أن بعض اللغات توفر دعمًا مدمجًا يُسهّل على المبرمج تخزين الدوال مؤقتًا، بينما تقوم لغات أخرى بتخزين دوال معينة افتراضيًا.
استُخدمت تقنية التخزين المؤقت أيضًا في سياقات أخرى (ولأغراض أخرى غير تحسين السرعة)، مثل تحليل الانحدار التنازلي المتبادل البسيط . [ 1 ] في سياق بعض لغات البرمجة المنطقية ، تُعرف تقنية التخزين المؤقت أيضًا باسم الجدولة . [ 2 ]
أصل الكلمة
صاغ دونالد ميتشي مصطلح "التخزين المؤقت" عام 1968 [ 3 ] ، وهو مشتق من الكلمة اللاتينية memorandum (بمعنى "أن يُتذكر")، والتي تُختصر عادةً إلى memo في اللغة الإنجليزية الأمريكية، وبالتالي يحمل معنى "تحويل نتائج دالة ما إلى شيء يُتذكر". ورغم أن مصطلح "التخزين المؤقت " قد يُخلط بينه وبين "الحفظ " (لأنهما متقاربان لغويًا )، إلا أن مصطلح "التخزين المؤقت" له معنى متخصص في مجال الحوسبة.
ملخص
عند استدعاء دالة مُخزَّنة مؤقتًا (memoized) لأول مرة بمجموعة مُدخلات مُحددة، فإنها تُخزِّن هذه المُدخلات مع النتائج المحسوبة. وعند استدعائها لاحقًا بنفس المُدخلات المُخزَّنة، تُعيد الدالة النتائج المُخزَّنة بدلًا من إعادة حسابها، مما يُلغي تكلفة إعادة الحساب. قد تكون مجموعة الارتباطات المُخزَّنة مجموعة ثابتة الحجم يتم التحكم بها بواسطة خوارزمية استبدال، أو مجموعة ثابتة، وذلك حسب طبيعة الدالة واستخدامها. لا يُمكن تخزين دالة مؤقتًا إلا إذا كانت شفافة مرجعيًا ؛ أي فقط إذا كان لاستدعاء الدالة نفس تأثير استبدال استدعاء الدالة بقيمتها المُعادة. (مع ذلك، توجد استثناءات خاصة لهذا القيد). على الرغم من ارتباط التخزين المؤقت بجداول البحث ، نظرًا لاستخدامه غالبًا لهذه الجداول في تنفيذه، إلا أنه يُملأ ذاكرة التخزين المؤقت للنتائج بشكل شفاف أثناء التنفيذ، بدلًا من الحاجة إلى توفيرها مُسبقًا.
تُحسَّن الدوال المُخزَّنة مؤقتًا لزيادة سرعتها على حساب زيادة استهلاكها لمساحة ذاكرة الحاسوب . ويُطلق على "تكلفة" الوقت والمساحة للخوارزميات اسمٌ خاص في مجال الحوسبة: التعقيد الحسابي . لكل دالة تعقيد حسابي زمني (أي أنها تستغرق وقتًا للتنفيذ) ومكاني .
على الرغم من وجود مفاضلة بين المساحة والوقت (أي أن المساحة المستخدمة تُكتسب مع زيادة السرعة)، إلا أن هذا يختلف عن بعض التحسينات الأخرى التي تنطوي على مفاضلة بين الوقت والمساحة، مثل تقليل حجم العمليات ، في أن التخزين المؤقت هو تحسين يتم أثناء التشغيل وليس أثناء الترجمة . علاوة على ذلك، قد يستبدل تقليل حجم العمليات عملية مكلفة مثل الضرب بعملية أقل تكلفة مثل الجمع، وقد تكون نتائج التوفير مرتبطة بشكل كبير بالجهاز (غير قابلة للنقل بين الأجهزة)، بينما يُعد التخزين المؤقت استراتيجية أكثر استقلالية عن الجهاز ومتوافقة مع مختلف المنصات .
لنفترض دالة الشفرة الزائفة التالية لحساب مضروب العدد n :
دالة المضروب ( حيث n عدد صحيح غير سالب) إذا كانت قيمة n تساوي صفرًا، إرجاع 1 [ بحسب الاصطلاح القائل بأن 0! = 1 ] آخر إرجاع مضروب ( ن - 1) مضروبًا في ن [ استدعاء مضروب بشكل متكرر مع المعامل 1 أقل من ن ] نهاية الشرط نهاية الدالة
لكل عدد صحيح n بحيث يكون ، تكون n ≥ 0النتيجة النهائية للدالة ثابتة ؛ فإذا تم استدعاؤها كـ ، تكون النتيجة بحيث يتم دائمًا إسناد القيمة 6 إلى x. يتطلب التنفيذ غير المُخزَّن أعلاه، نظرًا لطبيعة الخوارزمية التكرارية المستخدمة، n + 1 استدعاءً للدالة للوصول إلى نتيجة، ولكل استدعاء من هذه الاستدعاءات تكلفة مرتبطة به تتمثل في الوقت الذي تستغرقه الدالة لإرجاع القيمة المحسوبة. اعتمادًا على الجهاز، قد تكون هذه التكلفة مجموع:factorialx = factorial(3)factorial
- تكلفة إعداد إطار مكدس الاستدعاءات الوظيفية.
- تكلفة مقارنة n بـ 0.
- تكلفة طرح 1 من n .
- تكلفة إعداد إطار مكدس الاستدعاءات المتكررة. (كما سبق ذكره.)
- تكلفة ضرب نتيجة الاستدعاء المتكرر
factorialفي n . - تكلفة تخزين نتيجة الإرجاع بحيث يمكن استخدامها بواسطة سياق الاستدعاء.
في التنفيذ غير المُخزَّن، يتضمن كل استدعاء من المستوى الأعلى factorialالتكلفة التراكمية للخطوات من 2 إلى 6 بما يتناسب مع القيمة الأولية لـ n .
فيما يلي نسخة مُخزّنة من factorialالدالة:
دالة المضروب ( حيث n عدد صحيح غير سالب) إذا كانت قيمة n تساوي صفرًا، إرجاع 1 [ بحسب الاصطلاح القائل بأن 0! = 1 ] وإلا إذا كان n موجودًا في جدول البحث ، إرجاع قيمة جدول البحث لـ n آخر ليكن x = مضروب(n – 1) مضروبًا في n [ استدعاء مضروب بشكل متكرر مع المعامل 1 أقل من n ] قم بتخزين x في جدول البحث في الخانة رقم n [ احتفظ بنتيجة n! لاستخدامها لاحقًا ] إرجاع x نهاية الشرط نهاية الدالة
في هذا المثال تحديدًا، إذا factorialتم استدعاء الدالة أولًا بالقيمة 5، ثم استدعاؤها لاحقًا بأي قيمة أقل من أو تساوي 5، فسيتم تخزين قيم الإرجاع هذه مؤقتًا، لأن factorialالدالة ستُستدعى بشكل متكرر بالقيم 5، 4، 3، 2، 1، و0، وسيتم تخزين قيم الإرجاع لكل منها . إذا تم استدعاؤها بعد ذلك برقم أكبر من 5، مثل 7، فسيتم إجراء استدعاءين متكررين فقط (7 و6)، وسيتم تخزين قيمة 5! من الاستدعاء السابق. بهذه الطريقة، يسمح التخزين المؤقت للدالة بأن تصبح أكثر كفاءة من حيث الوقت كلما زاد عدد مرات استدعائها، مما يؤدي في النهاية إلى تسريع إجمالي.
يُعد نمط Singleton مثالًا متطرفًا على التخزين المؤقت ، وتحديدًا تنفيذ دالة getter الخاصة به - وهي دالة تقوم بإنشاء كائن عند الاستدعاء الأول، وتخزين النسخة مؤقتًا، وإرجاع نفس الكائن في جميع الاستدعاءات اللاحقة.
اعتبارات أخرى
البرمجة الوظيفية
تُستخدم تقنية التخزين المؤقت (Memoization) بكثرة في مُجمِّعات لغات البرمجة الوظيفية ، التي غالبًا ما تعتمد استراتيجية التقييم بالاسم . ولتجنب العبء الزائد الناتج عن حساب قيم الوسائط، تستخدم مُجمِّعات هذه اللغات بكثرة دوالًا مساعدة تُسمى " ثونكس" (thunks) لحساب قيم الوسائط، وتُخزِّن هذه الدوال مؤقتًا لتجنب تكرار العمليات الحسابية.
التخزين المؤقت التلقائي
بينما يُمكن إضافة التخزين المؤقت للدوال داخليًا وبشكل صريح من قِبل مُبرمج الحاسوب بنفس طريقة factorialتنفيذ النسخة المُخزّنة مؤقتًا المذكورة أعلاه، يُمكن أيضًا تخزين الدوال الشفافة مرجعيًا مؤقتًا تلقائيًا خارجيًا . [ 1 ] لا تقتصر تطبيقات التقنيات التي استخدمها بيتر نورفيج على لغة Common Lisp (اللغة التي عرض فيها بحثه التخزين المؤقت التلقائي)، بل تشمل أيضًا لغات برمجة أخرى متنوعة . كما تم استكشاف تطبيقات التخزين المؤقت التلقائي رسميًا في دراسة إعادة كتابة المصطلحات [ 4 ] والذكاء الاصطناعي . [ 5 ]
في لغات البرمجة التي تُعتبر فيها الدوال كائنات من الدرجة الأولى (مثل Lua و Python و Perl [ 6 ] )، يُمكن تطبيق التخزين المؤقت التلقائي عن طريق استبدال الدالة (أثناء التشغيل) بقيمتها المحسوبة بمجرد حساب قيمة لمجموعة معينة من المعاملات. ويمكن للدالة التي تُجري هذا الاستبدال أن تُغلّف أي دالة شفافة مرجعيًا. انظر إلى الشفرة الزائفة التالية (حيث يُفترض أن الدوال قيم من الدرجة الأولى):
دالة الاستدعاء المُخزّن ( F هو مُعامل كائن الدالة) إذا لم يكن للملف F أي قيم مصفوفة مرفقة ، قم بتخصيص مصفوفة ترابطية تسمى القيم ؛ قم بإرفاق قيم بـ F ؛ نهاية الشرط؛ إذا كانت F.values [arguments] فارغة، فإن F.values [ arguments ] = F (arguments)؛ نهاية الشرط؛ أعد F. values[arguments] ; نهاية الدالة
لاستدعاء نسخة مُخزّنة تلقائيًا factorialباستخدام الاستراتيجية المذكورة أعلاه، بدلاً من الاستدعاء factorialالمباشر، يستدعي الكود الدالة `require` . يتحقق كل استدعاء أولًا من وجود مصفوفة مُخصصة لتخزين النتائج، وإذا لم تكن موجودة، يُلحق تلك المصفوفة. إذا لم يكن هناك عنصر في الموضع (حيث تُستخدم `require` كمفتاح للمصفوفة الترابطية)، يُجرى استدعاء فعلي للدالة `require` مع الوسائط المُقدمة. أخيرًا، يُعاد العنصر الموجود في المصفوفة عند موضع المفتاح إلى المُستدعي.memoized-call(factorial)(n)values[arguments]argumentsfactorial
تتطلب الاستراتيجية المذكورة أعلاه تغليفًا صريحًا عند كل استدعاء لدالة سيتم تخزينها مؤقتًا. في اللغات التي تسمح بالإغلاقات ، يمكن تنفيذ التخزين المؤقت ضمنيًا عبر مصنع دوال يُعيد كائن دالة مُغلّفة ومُخزّنة مؤقتًا بنمط مُزخرف . في الشفرة الزائفة، يمكن التعبير عن ذلك كما يلي:
دالة بناء-دالة-مخزنة-مؤقتة ( F هو مُعامل كائن دالة) قم بتخصيص كائن دالة يسمى memoized-version ؛ let memoized-version(arguments) be إذا لم يكن للكائن self أي قيم مصفوفة مرفقة، فإن [ self هو مرجع لهذا الكائن ] قم بتخصيص مصفوفة ترابطية تسمى القيم ؛ إرفاق القيم بالذات ؛ نهاية الشرط؛ إذا كانت قيمة self.values[arguments] فارغة، self.values [arguments] = F (arguments); نهاية الشرط؛ أعد قيمة self.values [arguments] ؛ end let; إرجاع النسخة المخزنة مؤقتًا ؛ نهاية الدالة
بدلاً من استدعاء الدالة ، يتم إنشاء factorialكائن دالة جديد على النحو التالي:memfact
memfact = construct-memoized-unctor(factorial)
يفترض المثال أعلاه أن الدالة factorialقد تم تعريفها مسبقًا قبل استدعائها construct-memoized-functor. من هذه النقطة فصاعدًا، يتم استدعاء الدالة كلما رغبنا في حساب مضروب العدد n . في لغات مثل Lua، توجد تقنيات أكثر تطورًا تسمح باستبدال دالة بدالة جديدة تحمل نفس الاسم، مما يتيح ما يلي:memfact(n)
المضروب = بناء دالة مُخزّنة (المضروب)
بشكل أساسي، تتضمن هذه التقنيات ربط كائن الدالة الأصلي بالدالة المُنشأة وإعادة توجيه الاستدعاءات إلى الدالة الأصلية التي يتم تخزينها مؤقتًا عبر اسم مستعار عندما تكون هناك حاجة إلى استدعاء الدالة الفعلية (لتجنب التكرار اللانهائي )، كما هو موضح أدناه:
دالة بناء-دالة-مخزنة-مؤقتة ( F هو مُعامل كائن دالة) قم بتخصيص كائن دالة يسمى memoized-version ؛ let memoized-version (arguments) be إذا لم يكن للكائن self أي قيم مصفوفة مرفقة، فإن [ self هو مرجع لهذا الكائن ] قم بتخصيص مصفوفة ترابطية تسمى القيم ؛ إرفاق القيم بالذات ؛ قم بتخصيص كائن دالة جديد يسمى الاسم المستعار ؛ إرفاق اسم مستعار بالذات ؛ [ لإمكانية استدعاء F بشكل غير مباشر لاحقاً ] self.alias = F ; نهاية الشرط؛ إذا كانت قيمة self.values[arguments] فارغة، self.values [arguments] = self.alias ( arguments); [ ليست استدعاءً مباشرًا للدالة F ] نهاية الشرط؛ أعد قيمة self.values [arguments] ؛ end let; إرجاع النسخة المخزنة مؤقتًا ؛ نهاية الدالة
(ملاحظة: قد تتم إدارة بعض الخطوات الموضحة أعلاه ضمنيًا بواسطة لغة التنفيذ، وهي مقدمة للتوضيح فقط.)
المحللات
عندما يحاول محلل نحوي من أعلى إلى أسفل تحليل مدخلات غامضة بالنسبة لقواعد نحوية خالية من السياق غامضة ، فقد يحتاج إلى عدد هائل من الخطوات (مقارنةً بطول المدخلات) لتجربة جميع بدائل القواعد النحوية الخالية من السياق لإنتاج جميع أشجار التحليل الممكنة. وهذا بدوره يتطلب مساحة ذاكرة هائلة. في عام 1991، استكشف بيتر نورفيج تقنية التخزين المؤقت كاستراتيجية تحليل ، حيث أثبت إمكانية توليد خوارزمية مشابهة لاستخدام البرمجة الديناميكية ومجموعات الحالات في خوارزمية إيرلي (1970)، والجداول في خوارزمية CYK لكوك ويونغر وكاسامي، وذلك من خلال إدخال التخزين المؤقت التلقائي إلى محلل نحوي بسيط يعتمد على التراجع التكراري لحل مشكلة التعقيد الزمني الهائل. [ 1 ] وتتلخص الفكرة الأساسية في منهج نورفيج في أنه عند تطبيق محلل نحوي على المدخلات، تُخزن النتيجة في جدول تخزين مؤقت لإعادة استخدامها لاحقًا إذا أُعيد تطبيق المحلل نفسه على المدخلات نفسها.
استخدم ريتشارد فروست وباربرا شيدلوفسكي أيضًا تقنية التخزين المؤقت لتقليل التعقيد الزمني الأسي لمُركِّبات المُحلِّل النحوي ، واصفين النتيجة بأنها مُعالِج لغة وظيفي بحت يعتمد على التخزين المؤقت ويتراجع من أعلى إلى أسفل. [ 7 ] بيّن فروست أنه يُمكن استخدام مُركِّبات المُحلِّل النحوي الأساسية المُخزَّنة مؤقتًا كعناصر بناء لإنشاء مُحلِّلات نحوية مُعقَّدة كمواصفات قابلة للتنفيذ لقواعد اللغة الخالية من السياق. [ 8 ] [ 9 ]
تمت دراسة التخزين المؤقت مرة أخرى في سياق التحليل النحوي عام 1995 من قبل مارك جونسون ويوشين دوري. [ 10 ] [ 11 ] وفي عام 2002، تم فحصه بعمق كبير من قبل برايان فورد في شكل يسمى تحليل باكرات . [ 12 ]
في عام ٢٠٠٧، وصف فروست وحافظ وكالاغان خوارزمية تحليل نحوي من أعلى إلى أسفل تستخدم التخزين المؤقت لتجنب العمليات الحسابية الزائدة، وذلك لاستيعاب أي شكل من أشكال قواعد اللغة الخالية من السياق الغامضة في وقت متعدد الحدود ( Θ (n⁴ ) للقواعد النحوية اليسارية المتكررة وΘ(n³ ) للقواعد النحوية غير اليسارية المتكررة). تتطلب خوارزمية التحليل النحوي من أعلى إلى أسفل مساحة متعددة الحدود لأشجار التحليل النحوي الغامضة التي قد تكون أسية، وذلك من خلال "التمثيل المضغوط" و"تجميع الغموض المحلي". يُقارن تمثيلهم المضغوط بالتمثيل المضغوط لتوميتا للتحليل النحوي من أسفل إلى أعلى . [ ١٣ ] لا يقتصر استخدامهم للتخزين المؤقت على استرجاع النتائج المحسوبة مسبقًا عند تطبيق محلل نحوي على نفس موضع الإدخال بشكل متكرر (وهو أمر ضروري لمتطلبات الوقت متعدد الحدود)؛ بل إنه متخصص لأداء المهام الإضافية التالية:
- تستوعب عملية التخزين المؤقت (التي يمكن اعتبارها بمثابة "غلاف" حول أي تنفيذ للمحلل اللغوي) عملية تحليل متكررة يسارية مباشرة متزايدة باستمرار عن طريق فرض قيود على العمق فيما يتعلق بطول الإدخال وموضع الإدخال الحالي.
- تحدد عملية البحث في جدول الملاحظات الخاص بالخوارزمية إمكانية إعادة استخدام نتيجة محفوظة من خلال مقارنة سياقها الحسابي مع السياق الحالي للمحلل. وتُعد هذه المقارنة السياقية أساسية لاستيعاب الاستدعاء الذاتي الأيسر غير المباشر (أو الخفي) .
- عند إجراء عملية بحث ناجحة في جدول مؤقت، بدلاً من إرجاع مجموعة النتائج الكاملة، فإن العملية لا تُرجع سوى مراجع النتيجة الفعلية، مما يؤدي في النهاية إلى تسريع الحساب الإجمالي.
- أثناء تحديث جدول التخزين المؤقت، تقوم عملية التخزين المؤقت بتجميع النتائج الغامضة (التي قد تكون أسية) وتضمن متطلبات المساحة متعددة الحدود.
وصف كلٌّ من فروست وحافظ وكالاغان تطبيق الخوارزمية في PADL'08 كمجموعة من الدوال العليا (تُسمى مُركِّبات المُحلِّل ) في لغة هاسكل ، مما يُتيح إنشاء مواصفات قابلة للتنفيذ مباشرةً لقواعد اللغة الخالية من السياق (CFGs) كمعالجات لغوية. وتُعدُّ قدرة خوارزميتهم متعددة الحدود على استيعاب "أي شكل من أشكال قواعد اللغة الخالية من السياق الغامضة" مع التحليل من أعلى إلى أسفل أمرًا بالغ الأهمية فيما يتعلق بتحليل بناء الجملة والدلالات أثناء معالجة اللغة الطبيعية . يُمكنكم الاطلاع على المزيد من المعلومات حول الخوارزمية وتفاصيل تطبيقها على موقع X-SAIGA .
على الرغم من أن نورفيج قد حسّن من قوة المحلل اللغوي من خلال التخزين المؤقت، إلا أن المحلل المُحسّن ظلّ معقدًا زمنيًا مثل خوارزمية إيرلي، مما يُظهر حالة استخدام التخزين المؤقت لغرض آخر غير تحسين السرعة. يُقدّم جونسون ودوري [ 11 ] تطبيقًا آخر للتخزين المؤقت لا يتعلق بالسرعة: استخدام التخزين المؤقت لتأخير حلّ القيود اللغوية إلى نقطة في التحليل حيث تتراكم معلومات كافية لحلّ تلك القيود. في المقابل، في تطبيق التخزين المؤقت لتحسين السرعة، أثبت فورد أن التخزين المؤقت يمكن أن يضمن تحليل قواعد التعبير النحوي في وقت خطي حتى تلك اللغات التي ينتج عنها سلوك تراجع في أسوأ الحالات. [ 12 ]
انظر إلى القواعد النحوية التالية :
S → (A c ) | (B d ) A → X ( a | b ) ب → س ب س → س [س]
(ملاحظة توضيحية: في المثال أعلاه، يُقرأ الإنتاج S → (A c ) | (B d ) على النحو التالي: " S إما A متبوعًا بـ c أو B متبوعًا بـ d ". ويُقرأ الإنتاج X → x [X] على النحو التالي: " X هو x متبوعًا بـ X اختياري ".)
تُنتج هذه القواعد النحوية أحد الأشكال الثلاثة التالية للسلسلة النصية : xac أو xbc أو xbd (حيث يُفهم من x هنا أنها تعني حرف x واحدًا أو أكثر ). بعد ذلك، فكّر في كيفية تأثير هذه القواعد النحوية، المستخدمة كمواصفة تحليل، على تحليل السلسلة النصية xxxxxbd من أعلى إلى أسفل ومن اليسار إلى اليمين :
- ستتعرف القاعدة A على xxxxxb (عن طريق النزول أولاً إلى X للتعرف على x واحد ، ثم النزول مرة أخرى إلى X حتى يتم استهلاك جميع x ، ثم التعرف على b )، ثم تعود إلى S ، وتفشل في التعرف على c . بعد ذلك، سينزل البند التالي من S إلى B، والذي بدوره سينزل مرة أخرى إلى X ويتعرف على x من خلال العديد من الاستدعاءات المتكررة إلى X ، ثم b ، ويعود إلى S ويتعرف أخيرًا على d .
يكمن المفهوم الأساسي هنا في عبارة " ينحدر مرة أخرى إلى X" . تُعرف عملية التطلع إلى الأمام، ثم الفشل، ثم التراجع، ثم إعادة محاولة البديل التالي في التحليل النحوي باسم "التراجع"، وهو في الأساس ما يتيح فرصًا للتخزين المؤقت في التحليل النحوي. لنفترض دالة RuleAcceptsSomeInput(Rule, Position, Input)، حيث تكون المعاملات كما يلي:
Ruleهذا هو اسم القاعدة قيد النظر.Positionيمثل هذا الإزاحة التي يتم النظر فيها حاليًا في المدخلات.Inputهذا هو المدخل قيد الدراسة.
لنفترض أن القيمة المُعادة من الدالة RuleAcceptsSomeInputهي طول المدخلات المقبولة Rule، أو صفر إذا لم تقبل تلك القاعدة أي مدخلات عند ذلك الموضع في السلسلة. في سيناريو التراجع مع هذا النوع من التخزين المؤقت، تكون عملية التحليل كما يلي:
- عندما تنزل القاعدة A إلى X عند الإزاحة 0، فإنها تخزن الطول 5 مقابل ذلك الموضع والقاعدة X. بعد فشلها عند d ، تقوم القاعدة B ، بدلاً من النزول مرة أخرى إلى X ، بالاستعلام عن الموضع 0 مقابل القاعدة X في محرك التخزين المؤقت، ويتم إرجاع طول 5 إليها، مما يوفر عليها عناء النزول مرة أخرى إلى X ، وتستمر كما لو أنها نزلت إلى X بنفس عدد المرات السابقة.
في المثال أعلاه، قد يحدث نزول واحد أو أكثر إلى X ، مما يسمح بوجود سلاسل نصية مثل xxxxxxxxxxxxxxxxbd . في الواقع، قد يكون هناك أي عدد من x قبل b . بينما يجب على استدعاء S النزول بشكل متكرر إلى X بعدد مرات وجود x، لن يضطر B أبدًا إلى النزول إلى X على الإطلاق، لأن القيمة المُعادة ستكون 16 (في هذه الحالة تحديدًا).RuleAcceptsSomeInput(X, 0, xxxxxxxxxxxxxxxxbd)
كما أن المحللات التي تستخدم المسندات النحوية قادرة أيضاً على تخزين نتائج تحليل المسندات مؤقتاً، مما يقلل من مثل هذه التركيبات:
S → (A)؟ A أ → /* قاعدة ما */
إلى نزول واحد إلى أ .
إذا قام محلل نحوي بإنشاء شجرة تحليل أثناء عملية التحليل، فعليه تخزين ليس فقط طول المدخلات المطابقة عند إزاحة معينة لقاعدة محددة، بل عليه أيضًا تخزين الشجرة الفرعية الناتجة عن تلك القاعدة عند تلك الإزاحة في المدخلات، لأن استدعاءات القاعدة اللاحقة من قِبل المحلل لن تقوم فعليًا بالنزول وإعادة بناء تلك الشجرة. وللسبب نفسه، يجب على خوارزميات المحلل النحوي المُخزَّنة التي تُولِّد استدعاءات لرمز خارجي (يُسمى أحيانًا روتين إجراء دلالي ) عند مطابقة قاعدة ما، استخدام آلية ما لضمان استدعاء هذه القواعد بترتيب مُتوقع.
بما أنه بالنسبة لأي محلل نحوي يدعم التراجع أو التحقق من المسندات النحوية، لن تحتاج كل قواعد اللغة إلى التراجع أو التحقق من المسندات، فإن عبء تخزين نتائج تحليل كل قاعدة مقابل كل إزاحة في المدخلات (وتخزين شجرة التحليل إذا كانت عملية التحليل تقوم بذلك ضمنيًا) قد يُبطئ المحلل النحوي. ويمكن التخفيف من هذا التأثير عن طريق الاختيار الصريح للقواعد التي سيخزنها المحلل النحوي مؤقتًا. [ 14 ]
انظر أيضاً
- الحوسبة التقريبية – فئة من التقنيات لتحسين الكفاءة
- نظرية التعقيد الحسابي – مزيد من المعلومات حول تعقيد الخوارزميات
- سلسلة الموجه – تحديد موقع المتغيرات الحرة في التعبيرات بسرعة
- نمط Flyweight – نمط تصميم برمجة كائنية ، يستخدم أيضًا نوعًا من التخزين المؤقت
- هاشلايف – تقنية تخزين مؤقت لتسريع حساب الأوتوماتا الخلوية
- التقييم الكسول – يشترك في بعض المفاهيم مع التخزين المؤقت
- العرض المادي – التخزين المؤقت المماثل في استعلامات قاعدة البيانات
- التقييم الجزئي – تقنية ذات صلة لتحسين البرامج تلقائيًا
مراجع
- 1 2 3 نورفيج، بيتر (1991). "تقنيات التخزين المؤقت التلقائي مع تطبيقات على التحليل النحوي الخالي من السياق" . اللغويات الحاسوبية . 17 (1): 91-98 .
- ↑ وارن، ديفيد س. (1992-03-01). "الذاكرة لبرامج المنطق" . اتصالات رابطة مكائن الحوسبة . 35 (3): 93-111 . doi : 10.1145/131295.131299 . ISSN 0001-0782 .
- ↑ ميتشي، دونالد (1968). ""وظائف "المذكرات" والتعلم الآلي" (ملف PDF) . مجلة نيتشر . 218 (5136): 19-22 . رمز Bibcode : 1968Natur.218...19M . doi : 10.1038/218019a0 . S2CID 4265138 .
- ↑ هوفمان، بيرتولد (1992). "إعادة كتابة المصطلحات باستخدام المشاركة والتخزين المؤقت". في كيرشنر، هـ.؛ ليفي، ج. (محرران). البرمجة الجبرية والمنطقية: وقائع المؤتمر الدولي الثالث، فولتيرا، إيطاليا، 2-4 سبتمبر 1992. سلسلة محاضرات في علوم الحاسوب. المجلد 632. برلين: سبرينغر. الصفحات 128-142 . doi : 10.1007/BFb0013824 . ISBN 978-3-540-55873-6.
- ↑ مايفيلد، جيمس؛ وآخرون (1995). "استخدام التخزين المؤقت التلقائي كأداة هندسة برمجيات في أنظمة الذكاء الاصطناعي الواقعية" (ملف PDF) . وقائع المؤتمر الحادي عشر لمعهد مهندسي الكهرباء والإلكترونيات حول الذكاء الاصطناعي للتطبيقات (CAIA '95) . الصفحات 87-93 . doi : 10.1109/CAIA.1995.378786 . hdl : 11603/12722 . ISBN 0-8186-7070-3. S2CID 8963326 .
- ^ "بريكولاج: الحفظ" .
- ↑ فروست، ريتشارد؛ شيدلوفسكي، باربرا (1996). "معالجات لغات التراجع الوظيفية البحتة من أعلى إلى أسفل مع تخزين مؤقت" . مجلة علوم الحاسوب والبرمجة . 27 (3): 263-288 . doi : 10.1016/0167-6423(96)00014-7 .
- ↑ فروست، ريتشارد (1994). "استخدام التخزين المؤقت لتحقيق تعقيد متعدد الحدود للمواصفات التنفيذية الوظيفية البحتة للمحللات غير الحتمية من أعلى إلى أسفل". إشعارات SIGPLAN . 29 (4): 23-30 . doi : 10.1145/181761.181764 . S2CID 10616505 .
- ↑ فروست، ريتشارد (2003). "التخزين المؤقت الأحادي نحو تقليل البحث مع الحفاظ على صحته". المؤتمر الكندي للذكاء الاصطناعي 2003. سلسلة محاضرات في علوم الحاسوب. المجلد 2671. الصفحات 66-80 . doi : 10.1007/3-540-44886-1_8 . ISBN 978-3-540-40300-5.
- ↑ جونسون، مارك (1995). "تخزين البيانات في التحليل النحوي من أعلى إلى أسفل". اللغويات الحاسوبية . 21 (3): 405-417 . arXiv : cmp-lg/9504016 . Bibcode : 1995cmp.lg....4016J .
- 1 2 جونسون، مارك ودوري، يوشين (1995). "تخزين القيود المتزامنة مؤقتًا". وقائع الاجتماع السنوي الثالث والثلاثين لجمعية اللغويات الحاسوبية . كامبريدج، ماساتشوستس. arXiv : cmp-lg/9504028 .
{{cite book}}: CS1 maint: موقع الناشر مفقود ( رابط ) - 1 2 فورد، برايان (2002). تحليل Packrat: خوارزمية عملية خطية الوقت مع التراجع (رسالة ماجستير). معهد ماساتشوستس للتكنولوجيا. hdl : 1721.1/87310 .
- ↑ توميتا، ماسارو (1985). التحليل النحوي الفعال للغة الطبيعية . بوسطن: كلوير. ISBN 0-89838-202-5.
- ↑ أكار، أوموت أ.؛ وآخرون (2003). "التخزين المؤقت الانتقائي". وقائع الندوة الثلاثين لجمعية ACM SIGPLAN-SIGACT حول مبادئ لغات البرمجة، 15-17 يناير 2003. المجلد 38. نيو أورليانز، لويزيانا. الصفحات 14-25 . arXiv : 1106.0447 . doi : 10.1145/640128.604133 .
{{cite book}}تم|journal=تجاهله ( مساعدة ) صيانة CS1: موقع الناشر مفقود ( رابط )
روابط خارجية
- أمثلة على التخزين المؤقت في لغات برمجة مختلفة
- groovy.lang.Closure#memoize() – Memoize هي ميزة في لغة Apache Groovy 1.8.
- Memoize – Memoize هي مكتبة صغيرة، كتبها تيم برادشو، لتنفيذ عملية التخزين المؤقت في لغة Common Lisp .
- IncPy – مترجم بايثون مخصص يقوم بالتخزين المؤقت التلقائي (بدون تعليقات توضيحية مطلوبة من المستخدم)
- وحدات الماكرو الخاصة بديف هيرمان لتعريف الإجراءات المخزنة مؤقتًا في Racket .
- Memoize.pm – وحدة Perl تقوم بتنفيذ وظائف التخزين المؤقت.
- التخزين المؤقت في جافا - مثال في جافا باستخدام فئات الوكيل الديناميكية لإنشاء نمط تخزين مؤقت عام. (نسخة مؤرشفة من http://www.onjava.com/pub/a/onjava/2003/08/20/memoization.html ).
- memoization.java - مكتبة تخزين مؤقتة بلغة جافا.
- C++Memo – إطار عمل لتخزين البيانات المؤقتة بلغة C++ .
- C-Memo – مكتبة عامة لتخزين البيانات المؤقتة للغة C، تم تنفيذها باستخدام وحدات ماكرو لتغليف وظائف المعالج المسبق.
- Tek271 Memoizer – برنامج تخزين مؤقت مفتوح المصدر مكتوب بلغة جافا باستخدام التعليقات التوضيحية وتطبيقات ذاكرة التخزين المؤقت القابلة للتوصيل.
- memoizable – جوهرة روبي تقوم بتنفيذ الطرق المخزنة مؤقتًا.
- التخزين المؤقت في بايثون - مثال على التخزين المؤقت في بايثون .
- التخزين المؤقت في OCaml - تم تنفيذه كامتداد لبنية Camlp4 .
- التخزين المؤقت في لغة لوا - مثالان لتطبيقات دالة التخزين المؤقت العامة في لغة لوا .
- التخزين المؤقت في برنامج Mathematica – التخزين المؤقت والتخزين المؤقت المحدود في برنامج Mathematica .
- التخزين المؤقت في جافا سكريبت - توسيع نموذج الدالة في جافا سكريبت (نسخة مؤرشفة من http://talideon.com/weblog/2005/07/javascript-memoization.cfm ).
- التخزين المؤقت في جافا سكريبت - أمثلة على التخزين المؤقت في جافا سكريبت باستخدام آلية التخزين المؤقت الخاصة وباستخدام مكتبة YUI
- X-SAIGA – مواصفات تنفيذية للقواعد. يحتوي على منشورات متعلقة بخوارزمية التحليل من أعلى إلى أسفل التي تدعم الاستدعاء الذاتي الأيسر والغموض في وقت ومساحة متعدد الحدود.
- التخزين المؤقت في لغة Scheme - مثال على التخزين المؤقت في لغة Scheme على صفحة ويب خاصة بالفصل الدراسي.
- التخزين المؤقت في المنطق التوافقي - خدمة ويب لتقليل المنطق التوافقي مع تخزين كل خطوة في قاعدة البيانات مؤقتًا.
- MbCache – طريقة التخزين المؤقت تؤدي إلى .NET .
- تحسين البرمجيات
- أداء الحاسوب
