سؤال

أحتاج إلى تحليل ملف xml وهو عمليًا صورة لبنية شجرة كبيرة جدًا، لذلك أستخدم فئة XmlReader لملء الشجرة "أثناء التنقل".يتم تمرير كل عقدة فقط إلى قطعة XML التي تتوقعها من العقدة الأم عبر وظيفة ReadSubtree().يتميز هذا بأنه لا داعي للقلق بشأن الوقت الذي تستهلك فيه العقدة جميع أبنائها.لكنني الآن أتساءل عما إذا كانت هذه فكرة جيدة بالفعل، نظرًا لأنه قد يكون هناك آلاف العقد وأثناء قراءة ملفات مصدر .NET، وجدت أنه يتم إنشاء كائنين جديدين (وربما أكثر) مع كل استدعاء لـ ReadSubtree، ولم يتم إجراء تخزين مؤقت للكائنات القابلة لإعادة الاستخدام (التي رأيتها).

ربما لم يكن يُعتقد أن ReadSubtree() يُستخدم على نطاق واسع، أو ربما لا أشعر بالقلق من أي شيء وأحتاج فقط إلى الاتصال بـ GC.Collect() بعد تحليل الملف...

نأمل أن يتمكن شخص ما من إلقاء بعض الضوء على هذا.

شكرا لك مقدما.

تحديث:

شكرا على الإجابات الجميلة والثاقبة.

لقد ألقيت نظرة أعمق على الكود المصدري لـ .NET ووجدته أكثر تعقيدًا مما كنت أتخيله في البداية.لقد تخليت أخيرًا عن فكرة استدعاء هذه الوظيفة في هذا السيناريو بالذات.كما أشار ستيفان، لا يتم تمرير قارئ XML مطلقًا إلى الغرباء ويمكنني الوثوق في الكود الذي يوزع تدفق XML (الذي كتبته بنفسي)، لذلك أفضل إجبار كل عقدة على أن تكون مسؤولة عن كمية البيانات التي تقوم بتحليلها يمكنك السرقة من الدفق بدلاً من استخدام وظيفة ReadSubtree() غير الدقيقة في النهاية لحفظ بضعة أسطر من التعليمات البرمجية فقط.

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

المحلول

يمنحك ReadSubTree() XmlReader الذي يغلف XmlReader الأصلي.يظهر هذا القارئ الجديد للمستهلكين كوثيقة كاملة.قد يكون هذا مهمًا إذا كانت التعليمات البرمجية التي تمررها إلى الشجرة الفرعية تعتقد أنها تحصل على مستند xml مستقل.على سبيل المثال، تبدأ خاصية العمق للقارئ الجديد عند 0.إنه غلاف رفيع جدًا، لذلك لن تستخدم أي موارد أكثر مما ستستخدمه إذا استخدمت XmlReader الأصلي مباشرة، في المثال الذي قدمته، من المحتمل أنك لا تحصل على الكثير من الشجرة الفرعية قارئ.

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

كما لاحظ ويل، لن ترغب مطلقًا في الاتصال بـ GC.Collect().لن يؤدي ذلك إلى تحسين الأداء أبدًا.

نصائح أخرى

بافتراض أن جميع الكائنات يتم إنشاؤها على الكومة العادية المُدارة، وليس على كومة الكائنات الكبيرة (أي أقل من 85 كيلو بايت)، لا ينبغي أن تكون هناك مشكلة هنا، وهذا هو بالضبط ما تم تصميم GC للتعامل معه.

أود أن أقترح أيضًا أنه ليست هناك حاجة للاتصال بـ GC.Collect في نهاية العملية، حيث أنه في جميع الحالات تقريبًا، يسمح السماح لـ GC بجدولة المجموعات نفسها بالعمل بالطريقة المثلى (انظر هذا بلوق وظيفة للحصول على شرح مفصل جدًا لـ GC والذي يفسر هذا أفضل بكثير مما أستطيع).

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