سؤال

أحاول تحسين مجموعة متزامنة تحاول تقليل خلاف القفل للقراءات. كان First Pass يستخدم قائمة مرتبطة ، والتي سمحت لي بقفل الكتابة فقط في حين أن العديد من القراءات المتزامنة يمكن أن تستمر في إلغاء حظرها. هذا يستخدم العرف IEnumerator إلى أَثْمَر قيمة الرابط التالي. بمجرد أن بدأت في مقارنة التكرار على المجموعة إلى سهل List<T> لقد لاحظت أن تنفيذي كان حوالي نصف سريع (ل from x in c select x على مجموعة من العناصر 1* م* حصلت 24ms إلى عن على List<T> و 49ms لمجموعتي).

لذلك اعتقدت أنني سأستخدم أ ReaderWriteLockSlim والتضحية بقليل من القراءات حتى أتمكن من استخدام أ List<T> كما تخزين داخلي. بما أنني يجب أن ألتقط قفل القراءة على بدء التكرار وإطلاقه عند الانتهاء ، فقد قمت أولاً بنمط العائد على IEnumerable, foreachجي على الداخلية List<T>. الآن كنت أحصل فقط 66ms.

لقد نظرت إلى ما تفعله القائمة بالفعل ويستخدم متجرًا داخليًا T[] وعرف IEnumerator هذا يحرك الفهرس للأمام ويعيد قيمة الفهرس الحالية. الآن ، يستخدم يدويًا T[] لأن التخزين يعني المزيد من أعمال الصيانة ، لكن مع, ، أنا أطارد microseconds.

ومع ذلك حتى محاكاة IEnumerator تحريك الفهرس على صفيف ، كان أفضل ما يمكنني فعله هو ~ 38ms. إذن ما يعطي List<T> صلصةها السرية أو بدلاً من ذلك ما هو التنفيذ الأسرع للتكرار؟

تحديث: تبين أن الجناة الرئيسي الخاص بي كان يدير تصحيح التصحيح ، بينما List<T> من الواضح أن ترجمة الإصدار. في الإصدار ، لا يزال تنفيذي أبطأ من الشعر List<T>, ، Altough on Mono أصبح الآن أسرع.

أحد الاقتراحات الأخرى التي تلقيتها من صديق هي أن BCL أسرع لأنه في GAC وبالتالي يمكن أن يحصل مسبقًا على النظام. سوف تضطر إلى وضع اختباري في GAC لاختبار تلك النظرية.

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

المحلول

يبدو أن الحصول على القفل على كل تكرار وإطلاقه بمثابة فكرة سيئة - لأنه إذا قمت بعمل Add أو Remove أثناء التكرار على القائمة ، سيؤدي ذلك إلى إبطال التكرار. List<T> بالتأكيد لا يحب ذلك ، على سبيل المثال.

هل تسمح حالة استخدامك للمتصلين بإخراج أ ReaderWriterLockSlim حول عملية التكرار بأكملها ، بدلاً من أساس كل عنصر؟ سيكون ذلك أكثر كفاءة و أكثر قوة. إذا لم يكن كذلك ، كيف تخطط للتعامل مع قضية التزامن؟ إذا أضاف الكاتب عنصرًا سابقًا من المكان الذي يمكنني فيه ، فإن التنفيذ البسيط سيعيد نفس العنصر مرتين. سيحدث العكس مع الإزالة - سيتخطى التكرار عنصرًا.

أخيرًا ، هل .NET 4.0 خيار؟ أعلم أن هناك بعض المجموعات المتزامنة المحسنة للغاية هناك ...

تحرير: لست متأكدًا تمامًا من ماهية وضعك الحالي فيما يتعلق ببناء جهاز تكرار باليد ، ولكن هناك شيء واحد قد ترغب في التحقيق فيه هو استخدام بنية لـ IEnumerator<T>, ، وجعل مجموعتك يعلن صراحة أنه يعيد ذلك - هذا ما List<T> يفعل. هو - هي يفعل يعني استخدام بنية قابلة للتغيير ، مما يجعل القطط تبكي في جميع أنحاء العالم ، ولكن إذا كان هذا أمرًا بالغ الأهمية للأداء وتعتقد أنه يمكنك العيش مع الرعب ، فهذا يستحق المحاولة على الأقل.

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