سؤال

قل أن هناك متغيرًا DICT ينمو بشكل كبير للغاية أثناء وقت التشغيل - إلى ملايين المفاتيح: أزواج القيمة.

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

إن مطالبة المترجم المترجم بعرض القول بأكمله فكرة سيئة ، ولكن هل سيكون على ما يرام طالما تم الوصول إلى مفتاح واحد في وقت واحد؟

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

المحلول

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

قال آخرون إن بضعة ملايين من العناصر لا ينبغي أن تشكل مشكلة ؛ لست متأكدًا. إن القولان العلوي نفسه (قبل حساب الذاكرة التي اتخذتها المفاتيح والقيم) مهمة. لبيثون 2.6 أو في وقت لاحق ، sys.getSizeOf يعطي بعض المعلومات المفيدة حول مقدار RAM الذي تتناوله هياكل Python المختلفة. بعض النتائج السريعة ، من Python 2.6 على جهاز OS X 64 بت:

>>> from sys import getsizeof
>>> getsizeof(dict((n, 0) for n in range(5462)))/5462.
144.03368729403149
>>> getsizeof(dict((n, 0) for n in range(5461)))/5461.
36.053470060428495

لذلك يتراوح النفقات العامة القلبية بين 36 بايت لكل عنصر و 144 بايت لكل عنصر على هذا الجهاز (القيمة الدقيقة اعتمادًا على مدى امتلاء جدول التجزئة الداخلي للقاموس ؛ هنا 5461 = 2 ** 14 // 3 هي واحدة من العتبات التي تم توسيع جدول التجزئة الداخلية). وذلك قبل إضافة النفقات العامة للعناصر القلبية نفسها ؛ إذا كانت جميعها سلاسل قصيرة (6 أحرف أو أقل ، على سبيل المثال) ، فلا يزال يضيف آخر> = 80 بايت لكل عنصر (ربما أقل إذا كانت العديد من المفاتيح المختلفة تشترك في نفس القيمة).

لذلك لن يستغرق الذي - التي العديد من الملايين من العناصر القشرية لاستنفاد ذاكرة الوصول العشوائي على آلة نموذجية.

نصائح أخرى

الشاغل الرئيسي بملايين العناصر ليس القاموس نفسه بقدر مقدار المساحة التي يشغلها كل عنصر من هذه العناصر. ومع ذلك ، ما لم تكن تفعل شيئًا غريبًا ، فمن المحتمل أن يناسبهم.

إذا كنت قد حصلت علىيل مع ملايين المفاتيح ، فمن المحتمل أنك تفعل شيئًا خاطئًا. يجب أن تفعل واحدة أو كليهما:

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

  2. استخدم قاعدة بيانات. يجب أن يأتي Python الخاص بك مع وحدة SQLite3 ، لذلك هذه بداية.

نعم ، بيثون dict يتم تخزينه في رام. عدد قليل من المفاتيح ليست مشكلة لأجهزة الكمبيوتر الحديثة. إذا كنت بحاجة إلى المزيد والمزيد من البيانات ونفد ذاكرة الوصول العشوائي ، فكر في استخدام قاعدة بيانات حقيقية. تشمل الخيارات DB العلائقية مثل SQLite (مدمج في Python ، بالمناسبة) أو متجر القيمة الرئيسية مثل Redis.

من غير المنطقي عرض ملايين العناصر في المترجم المترجم ، ولكن يجب أن يكون الوصول إلى عنصر واحد فعالًا للغاية.

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

from random import randint
a = {}
for i in xrange(10*10**6):
    a[i] = i

كيف يبدو هذا عند تشغيله؟ يستغرق حوالي 350 ميغابايت على نظامي والتي يجب أن يكون قابلاً للإدارة على أقل تقدير.

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