سؤال

لقد قررت استخدام PostSharp (الذي لا يمكن تمييزه عن السحر) لقراءة السمات و حفظ الوظائف.سيكون تجزئة استدعاء الوظيفة هو المفتاح والملف المخزن مؤقتًا (in سرعة) سيتم إرجاع النتيجة بدلاً من استدعاء الوظيفة مرة أخرى.من السهل peasy، ماك والجبن.

لقد قمت بالفعل استسلم على القدرة على اكتشاف الآثار الجانبية في الوظائف المزخرفة، والتي تبين أنها "مشكلة صعبة"، حتى بالنسبة للخبراء، وأنا لست كذلك بالتأكيد.بعد ذلك، يجب أن أعرف ما هي الوظائف الأخرى المرشحة للحفظ.

  • ماذا عن الأساليب التي تأخذ أنواع مرجعية معقدة كمعلمات؟
  • ماذا عن الأساليب التي تعتمد على البيانات الموجودة داخل الحالات التي يتم استدعاؤها منها؟

تتبادر إلى ذهنك كائنات بيانات ActiveRecord-esque عند تلك الأخيرة.

هل سأضطر إلى إعادة صياغة التعليمات البرمجية القديمة لدعم الحفظ؟

هل كانت مفيدة؟

المحلول

لا يمكنك حفظ دالة إلا إذا كانت جميع مدخلاتها عبارة عن أنواع قيم أو أنواع مرجعية غير قابلة للتغيير، وإذا كانت تقوم بإرجاع نوع قيمة أو مثيل جديد لنوع مرجعي، وإذا لم يكن لها أي آثار جانبية.فترة.

يعتمد الحفظ على التعيين الحتمي بين المدخلات والمخرجات.كل مكالمة ل F(a, b, c) حيث تحتوي a وb وc على نفس القيم، يجب أن تُرجع نفس النتيجة حتى يكون الحفظ ممكنًا.

إذا كانت المعلمة عبارة عن نوع مرجعي، فبالرغم من أن قيمتها لا تتغير، إلا أن الاستدعاءات المتعددة للدالة التي تستخدمها قد تؤدي إلى نتيجة مختلفة.مثال تافه:

public int MyFunction(MyType t)
{
   return t.Value;
}

Console.WriteLine(MyFunction(t));
t.Value++;
Console.WriteLine(MyFunction(t));

وبالمثل، إذا كانت دالة تعتمد على قيمة خارجية عنها، فإن الاستدعاءات المتعددة لتلك الدالة بنفس المعلمات يمكن أن تؤدي إلى نتائج مختلفة:

int Value = 0;

public int MyFunction(int input)
{
   return Value;
}

Console.WriteLine(MyFunction(1));
Value++;
Console.WriteLine(MyFunction(1));

وستساعدك الجنة إذا كانت وظيفتك المحفوظة تفعل شيئًا آخر غير إرجاع قيمة أو نوع مرجعي جديد:

int Value = 0;

public int MyFunction(int input)
{
   Value++;
   return input;
}

إذا قمت باستدعاء هذه الوظيفة 10 مرات، Value سيكون 10.إذا قمت بإعادة هيكلتها لاستخدام الحفظ ثم اتصلت بها 10 مرات، Value سيكون 1.

يمكنك البدء في السير على طريق اكتشاف كيفية حفظ الحالة، بحيث يمكنك تزوير وظيفة تحفظ نوعًا مرجعيًا.لكن ما تحفظه حقًا هو مجموعة القيم التي تعمل عليها الوظيفة.يمكنك بالمثل اختراق وظيفة محفوظة لها آثار جانبية بحيث تحدث آثارها الجانبية قبل الحفظ.لكن هذا كله يدعو إلى المتاعب.

إذا كنت ترغب في تنفيذ الحفظ في وظيفة تأخذ نوعًا مرجعيًا، فإن الطريقة الصحيحة هي إعادة هيكلة جزء الوظيفة الذي يعمل فقط على أنواع القيم، وحفظ تلك الوظيفة، على سبيل المثال:

public int MyFunction(MyType t)
{
   return t.Value + 1;
}

الى هذا:

public int MyFunction(MyType t)
{
   return MyMemoizableFunction(t.Value);
}

private int MyMemoizableFunction(int value)
{
   return value + 1;
}

أي أسلوب آخر لتنفيذ الحفظ تتخذه إما أ) يفعل نفس الشيء، من خلال وسائل أكثر غموضًا، أو ب) لن ينجح.

نصائح أخرى

حسنًا، أي وظيفة، من الناحية النظرية، هي مرشحة للحفظ.ومع ذلك، تذكر أن الحفظ يدور حول استبدال المساحة بالسرعة -

بشكل عام، هذا يعني أنه كلما زادت الحالة التي تتطلبها الوظيفة أو تعتمد عليها لحساب الإجابة، زادت تكلفة المساحة، مما يقلل من الرغبة في حفظ الطريقة.

كلا المثالين الخاصين بك هما في الأساس حالات تحتاج إلى حفظ المزيد من الحالة.وهذا له آثار جانبية.

أولاً، سيتطلب هذا مساحة ذاكرة أكبر بكثير لحفظ الوظيفة، حيث سيلزم حفظ المزيد من المعلومات.

ثانيًا، من المحتمل أن يؤدي هذا إلى إبطاء الوظيفة المحفوظة، نظرًا لأنه كلما زادت المساحة، زادت تكلفة البحث عن الإجابة، وكذلك زادت تكلفة العثور على ما إذا كانت النتيجة قد تم حفظها مسبقًا أم لا.

بشكل عام، أميل إلى النظر فقط في الوظائف التي تحتوي على عدد قليل من المدخلات المحتملة ومتطلبات تخزين منخفضة، ما لم تكن هناك تكلفة عالية جدًا في حساب الإجابة.

أعترف أن هذا غامض، لكنه جزء من "الفن" في الهندسة المعمارية.لا توجد إجابة "صحيحة" دون تنفيذ كلا الخيارين (الوظائف المحفوظة وغير المحفوظة)، والتنميط، والقياس.

لقد فكرت بالفعل في طريقة لتوفير حل AOP لتوفير الحفظ حول الوظيفة Foo, ، إذن ما الذي بقي لمعرفة ذلك؟

نعم، يمكنك تمرير كائن ذي تعقيد عشوائي كمعلمة إلى وظيفة محفوظة، طالما أنه غير قابل للتغيير، كما هو الحال مع كل الأشياء التي يعتمد عليها.مرة أخرى، ليس من السهل على الإطلاق اكتشاف ذلك بشكل ثابت في الوقت الحالي.

هل مازلت متمسكًا بفكرة أنه يمكنك فحص الكود بشكل ثابت من أجل تقديم المشورة للمستخدمين بشأن السؤال "هل من الجيد تطبيق الحفظ على الوظيفة؟ Foo?"

إذا جعلت ذلك أحد متطلباتك، فسوف تنضم إلى جهد بحثي عالمي استمر لسنوات عديدة حتى الآن.أعتقد أن هذا يعتمد على مدى طموحك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top