سؤال

اضطررت مؤخرًا إلى القيام ببعض الأمور الثقيلة في معالجة البيانات المخزنة في DataSet.لقد كان الأمر ثقيلًا بدرجة كافية، وانتهى بي الأمر باستخدام أداة للمساعدة في تحديد بعض الاختناقات في الكود الخاص بي.عندما كنت أقوم بتحليل الاختناقات، لاحظت أنه على الرغم من أن عمليات البحث في DataSet لم تكن بطيئة للغاية (لم تكن هي عنق الزجاجة)، إلا أنها كانت أبطأ مما كنت أتوقع.لقد افترضت دائمًا أن DataSets تستخدم نوعًا من تنفيذ نمط HashTable والذي من شأنه أن يجعل عمليات البحث O(1) (أو على الأقل هذا ما أعتقد أن HashTables هي عليه).يبدو أن سرعة عمليات البحث الخاصة بي أبطأ بكثير من ذلك.

كنت أتساءل عما إذا كان أي شخص يعرف أي شيء عن تنفيذ فئة DataSet الخاصة بـ .NET سيهتم بمشاركة ما يعرفه.

إذا قمت بشيء مثل هذا:

DataTable dt = new DataTable();
if(dt.Columns.Contains("SomeColumn"))
{
    object o = dt.Rows[0]["SomeColumn"];
}

ما مدى سرعة وقت البحث عن Contains(...) الطريقة، ولاسترجاع القيمة المراد تخزينها Object o؟كنت أعتقد أنه سريع جدًا مثل HashTable (بافتراض أن ما أفهمه حول HashTables صحيح) ولكن لا يبدو الأمر كذلك...

لقد كتبت هذا الرمز من الذاكرة لذا قد لا تكون بعض الأشياء "صحيحة من الناحية النحوية".

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

المحلول

عبر العاكس خطوات DataRow["ColumnName"] هي:

  1. احصل على DataColumn من ColumnName.يستخدم DataColumnCollection للصف ["ColumnName"].داخليًا، يقوم DataColumnCollection بتخزين DataColumns الخاص به في ملف Hastable.يا(1)
  2. احصل على فهرس صف DataRow.يتم تخزين الفهرس في عضو داخلي.يا(1)
  3. احصل على قيمة DataColumn في الفهرس باستخدام DataColumn[index].يقوم DataColumn بتخزين بياناته في عضو System.Data.Common.DataStorage (داخلي، مجرد):

    إرجاع dataColumnInstance._storage.Get(recordIndex);

    نموذج التنفيذ الملموس هو System.Data.Common.StringStorage (داخلي، مختوم).يقوم StringStorage (ووحدات DataStorages الملموسة الأخرى التي قمت بفحصها) بتخزين قيمها في مصفوفة.يقوم Get(recordIndex) ببساطة بالتقاط الكائن الموجود في مصفوفة القيمة في ملف RecordIndex.يا(1)

بشكل عام، أنت O(1) ولكن هذا لا يعني أن التجزئة واستدعاء الوظائف أثناء العملية يكونان بدون تكلفة.هذا يعني فقط أنها لا تكلف أكثر مع زيادة عدد DataRows أو DataColumns.

من المثير للاهتمام أن DataStorage يستخدم مصفوفة للقيم.لا أستطيع أن أتخيل أنه من السهل إعادة البناء عند إضافة صفوف أو إزالتها.

نصائح أخرى

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

const int SomeTable_SomeColumn = 0;

DataTable dt = new DataTable();
if(dt.Columns.Contains(SomeTable_SomeColumn))
{
    object o = dt.Rows[0][SomeTable_SomeColumn];
}

أتخيل أن أي عمليات بحث ستكون O(n)، لأنني لا أعتقد أنهم سيستخدمون أي نوع من أنواع التجزئة، لكنهم سيستخدمون في الواقع المزيد من المصفوفة للعثور على الصفوف والأعمدة.

في الواقع، أعتقد أن أسماء الأعمدة مخزنة في Hashtable.يجب أن يكون O(1) أو البحث المستمر عن عمليات البحث الحساسة لحالة الأحرف.إذا كان عليه أن ينظر في كل منها، فسيكون بالطبع O(n).

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