c# - .NET HashTable Vs Dictionary-هل يمكن أن يكون القاموس أسرع؟



collections (9)

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

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

سؤالي هو حقا ، ما قد تكون تلك الحالات؟ هل أنا مخطئ في افتراضاتي أعلاه؟ ما هي المواقف التي قد تستخدمها لاختيار واحدة فوق الأخرى (نعم ، آخرها غامض بعض الشيء).


Answers

مقالة MSDN: "يحتوي Dictionary<TKey, TValue> class على نفس وظيفة الفئة Hashtable . يحتوي Dictionary<TKey, TValue> لنوع معين (غير Object ) على أداء أفضل من Hashtable لأنواع القيم لأن عناصر Hashtable هي من نوع Object ، وبالتالي ، عادةً ما يحدث boxing و unboxing في حالة تخزين أو استرداد نوع القيمة ".

الرابط: http://msdn.microsoft.com/en-us/library/4yh14awz(v=vs.90).aspx


كلاهما بالفعل نفس الفئة (يمكنك النظر في التفكيك). تم إنشاء HashTable أولاً قبل .Net كان الأدوية البديلة. القاموس ، ومع ذلك هو فئة عامة ويعطيك فوائد الطباعة قوية. لن أستخدم HashTable أبدًا نظرًا لأن القاموس لن يكلفك شيئًا لاستخدامه.


فرق آخر مهم هو أن Hashtable خيط آمن. لقد قام Hashtable ببناء العديد من خيط القارئ / الكاتب الواحد (MR / SW) مما يعني أن Hashtable تسمح لكاتب واحد مع عدة قرائين بدون قفل. في حالة Dictionary لا يوجد سلامة الصفحات ، إذا كنت بحاجة إلى سلامة موضوع يجب عليك تنفيذ التزامن الخاص بك.

لمزيد من التفاصيل:

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

لا توفر فئات مجموعة .NET Framework 2.0 مثل List<T> ، و Dictionary<TKey, TValue> ، وما إلى ذلك أي مزامنة Dictionary<TKey, TValue> ؛ يجب أن يوفر رمز المستخدم كافة التزامن عند إضافة عناصر أو إزالتها على مؤشرات ترابط متعددة بشكل متزامن إذا كنت بحاجة إلى أمان اكتب سلامة الصفحات ، استخدم فئات المجموعات المتزامنة في .NET Framework. مزيد من القراءة هنا.



System.Collections.Generic.Dictionary<TKey, TValue> و System.Collections.Hashtable كلا الاحتفاظ بنية بيانات جدول تجزئة داخليًا. لا أحد منهم يضمن الحفاظ على ترتيب العناصر.

إذا تركنا القضايا المتعلقة بالملاكمة / إلغاء الصندوق جانباً ، فمعظم الأوقات ، ينبغي أن يكون لديهم أداء مشابه جداً.

الفرق البنيوي الأساسي بينهما هو أن Dictionary يعتمد على تسلسل (الاحتفاظ بقائمة من العناصر لكل مجموعة جدول تجزئة) لحل التضاربات بينما يستخدم Hashtable rehashing من أجل حل الاصطدام (عندما يحدث الاصطدام ، يحاول وظيفة هاش أخرى لتعيين المفتاح إلى a دلو).

هناك فائدة قليلة لاستخدام فئة Hashtable إذا كنت تستهدف .NET Framework 2.0+. تم تقديمه بشكل فعال عن طريق Dictionary<TKey, TValue> .


إذا كنت تهتم بالقراءة التي ستقوم دائمًا بإرجاع الكائنات بالترتيب الذي تم إدراجه في قاموس ، فقد يكون لديك نظرة على ذلك

OrderedDictionary - يمكن الوصول إلى القيم عبر فهرس صحيح (حسب ترتيب العناصر التي تمت إضافتها) SortedDictionary - يتم فرز العناصر تلقائيًا


الاختلافات بين Hashtable والقاموس

قاموس:

  • إرجاع القاموس خطأ إذا حاولنا العثور على مفتاح غير موجود.
  • قاموس أسرع من Hashtable لأنه لا يوجد الملاكمة و unboxing.
  • القاموس هو نوع عام مما يعني أنه يمكننا استخدامه مع أي نوع بيانات.

جدول هاش:

  • إرجاع Hashtable Null إذا حاولنا العثور على مفتاح غير موجود.
  • أبطأ Hashtable من القاموس لأنه يتطلب الملاكمة و unboxing.
  • Hashtable ليس نوعًا عامًا ،

الاختلاف المهم الآخر هو أن نوع Hashtable يدعم قراءات متعددة بدون قفل وكاتب واحد في نفس الوقت ، بينما لا يقوم القاموس.


إذا لم تكن بحاجة إلى list الأصلية dictionaries ، فيمكنك تعديلها في المكان باستخدام طريقة sort() باستخدام وظيفة مفتاح مخصص.

الوظيفة الرئيسية:

def get_name(d):
    """ Return the value of a key in a dictionary. """

    return d["name"]

list المطلوب فرزها:

data_one = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]

فرزها في المكان:

data_one.sort(key=get_name)

إذا كنت بحاجة إلى list الأصلية ، sorted() الدالة sorted() تمررها في list ووظيفة المفتاح ، ثم عيّن list إرجاعها إلى متغير جديد:

data_two = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
new_data = sorted(data_two, key=get_name)

طباعة data_one و new_data .

>>> print(data_one)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
>>> print(new_data)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]




c# .net collections dictionary hashtable