मेरी पहली बार यहाँ पोस्टिंग, तो मैं रास्ते से सही तरह में मेरे सवाल का,गिनती टकराव
पूछा है उम्मीद एक अजगर शब्दकोश में एक तत्व जोड़ने के बाद, यह करने के लिए अजगर पाने के लिए संभव है आपको बताते हैं कि उस तत्व को जोड़ने से टकराव हुआ? (और तत्व को रखने के लिए जगह खोजने से पहले टक्कर रिज़ॉल्यूशन रणनीति की कितनी जगहों की जांच की गई?)
मेरी समस्या यह है कि: मैं एक बड़ी परियोजना के हिस्से के रूप में शब्दकोश का उपयोग कर रहा हूं, और व्यापक प्रोफाइलिंग के बाद, मैंने पाया है कि सबसे धीमा कोड का हिस्सा शब्दकोशों का उपयोग करके लागू एक स्पैस दूरी मैट्रिक्स से निपट रहा है।
मैं जिन चाबियों का उपयोग कर रहा हूं वे पाइथन ऑब्जेक्ट्स की आईडी हैं, जो अद्वितीय पूर्णांक हैं, इसलिए मुझे पता है कि वे सभी हैंश अलग-अलग मानों के लिए हैं। लेकिन उन्हें एक शब्दकोश में डालने से सिद्धांत में टकराव हो सकता है। मुझे विश्वास नहीं है कि शब्दकोश टकराव ऐसी चीज है जो मेरे कार्यक्रम को धीमा कर रही है, लेकिन मैं उन्हें अपनी पूछताछ से खत्म करना चाहता हूं।
तो, उदाहरण के लिए, यह देखते हुए निम्नलिखित शब्दकोश:
d = {}
for i in xrange(15000):
d[random.randint(15000000, 18000000)] = 0
आप अजगर कितने टकराव हुआ यह बनाते समय आपको बताने के लिए मिल सकता है?
मेरा वास्तविक कोड एप्लिकेशन के साथ उलझ गया है, लेकिन उपर्युक्त कोड एक शब्दकोश बनाता है जो मैं उपयोग कर रहा हूं।
दोहराने के लिए: मुझे नहीं लगता कि टकराव मेरे कोड को धीमा कर रहा है, मैं बस यह दिखाकर संभावना को खत्म करना चाहता हूं कि मेरे शब्दकोशों में कई टकराव नहीं हैं।
आपकी मदद के लिए धन्यवाद।
संपादित करें:
n = 1500
global collision_count
collision_count = 0
class Foo():
def __eq__(self, other):
global collision_count
collision_count += 1
return id(self) == id(other)
def __hash__(self):
#return id(self) # @John Machin: yes, I know!
return 1
objects = [Foo() for i in xrange(n)]
d = {}
for o in objects:
d[o] = 1
print collision_count
ध्यान दें कि जब आप एक वर्ग पर __eq__
परिभाषित करते हैं, अजगर आप एक TypeError: unhashable instance
अगर आप भी एक __hash__
समारोह परिभाषित नहीं करते देता है: कुछ कोड @Winston Ewert के समाधान को लागू करने।
यह अपेक्षा करता है कि यह काफी नहीं चलता है। यदि आपके पास __hash__
फ़ंक्शन return 1
है, तो आपको उम्मीद के अनुसार टकराव का भार मिलता है (1125560 मेरे सिस्टम पर एन = 1500 के लिए टकराव)। लेकिन return id(self)
के साथ, 0 टकराव हैं।
कोई भी जानता है कि यह 0 टकराव क्यों कह रहा है?
संपादित करें: मैंने इसे समझ लिया होगा।
क्या ऐसा इसलिए है क्योंकि __eq__
केवल तभी कहा जाता है जब __hash__
दो ऑब्जेक्ट्स के मान समान हैं, न कि उनके "क्रंच किए गए संस्करण" (जैसा कि जॉन जॉनिन ने इसे रखा है)?
आपका मतलब है कि आप जानना चाहते हैं कि आंतरिक निर्देश एल्गोरिदम ने किसी तत्व को खोजने के लिए किसी हैश तालिका की जांच की है या नहीं? क्या आप "टक्कर" से क्या मतलब है? –
कुछ अर्ध-प्रासंगिक जानकारी: 'हैश (-1) == हैश (-2) '। इसके अलावा, अंतराल में सभी इन्स x '-sys.maxint-1 <= x <= sys.maxint' में अद्वितीय हैंश हैं। हैशिंग लम्बी स्याही के लिए एल्गोरिदम यहां वर्णित है: http://effbot.org/zone/python-hash.htm – unutbu
"हैश मान -1 आरक्षित है (इसका उपयोग सी कार्यान्वयन में त्रुटियों को ध्वजांकित करने के लिए किया जाता है)। यदि हैश एल्गोरिदम इस मान को उत्पन्न करता है, हम बस इसके बजाय -2 का उपयोग करते हैं। " आउच। – UncleZeiv