सुपर उच्च प्रदर्शन C / C ++ हैश मैप (तालिका, शब्दकोश) [बंद]


84

मुझे उच्च-प्रदर्शन वाले हैश मैप डेटा संरचना में संरचनात्मक मूल्यों के लिए आदिम कुंजियों (उदाहरण, शायद लंबे समय) को मैप करने की आवश्यकता है।

मेरे कार्यक्रम में इन मानचित्रों में से कुछ सौ होंगे, और प्रत्येक मानचित्र में आमतौर पर कुछ हजार प्रविष्टियाँ होंगी। हालांकि, नक्शे लगातार "ताज़ा" या "मंथन" होंगे; लाखों संदेशों addऔर deleteसंदेशों के प्रसंस्करण की कल्पना करें ।

C या C ++ में कौन सी लाइब्रेरीज़ में डेटा संरचना होती है जो इस उपयोग के मामले में फिट होती है? या, आप अपने खुद के निर्माण की सिफारिश कैसे करेंगे? धन्यवाद!


1
क्या आपको अपने डेटा में कुंजी द्वारा खोज को संसाधित करने की आवश्यकता है?
गिलियूम लेबोर्जियोस

3
क्या अपडेट या पुनर्प्राप्ति अधिक लगातार होगी? (जोड़ें / हटाएं, या पढ़ें / अपडेट करें जो कुंजी को नहीं बदल रहा है)
फालस्ट्रो

stackoverflow.com/questions/266206/… । शायद यह एक अच्छी जगह है।
डंबकोडर

2
@roe:ऐड / डिलीट ऑपरेशंस बहुत ज्यादा (100x) ऑपरेशन से ज्यादा लगातार होते हैं।
हयवुड जाबलोमी

1
साढ़े चार साल बाद यह जानना दिलचस्प होगा कि आपकी आवश्यकताओं में सबसे अच्छा क्या था। यदि वर्तमान उत्तरों में से कोई भी संतोषजनक नहीं था, तो आप अपना स्वयं लिख सकते हैं और इसे स्वीकार कर सकते हैं।
वाल्टर ट्रॉस

जवाबों:


31

मैं आपको Google SparseHash (या C11 संस्करण Google SparseHash-c11 ) आज़माने की सलाह दूंगा और देखूंगा कि क्या यह आपकी आवश्यकताओं के अनुरूप है। उनके पास एक मेमोरी कुशल कार्यान्वयन है और साथ ही गति के लिए अनुकूलित है। मैंने बहुत समय पहले एक बेंचमार्क किया था, यह गति के संदर्भ में उपलब्ध सबसे अच्छा हैशटेबल कार्यान्वयन था (हालांकि कमियों के साथ)।


16
क्या आप यह बता सकते हैं कि कमियां क्या थीं?
हयवुड जाबलोमी

IIRC, यह एक मेमोरी समस्या थी, जब किसी तत्व को निकालते समय, तत्व को नष्ट कर दिया गया था, लेकिन इसकी मेमोरी अभी भी जीवित थी (एक कैश के रूप में मुझे लगता है)।
स्कैर्रोन

4
@ हयावुड जाब्लेमी: मुख्य दोष यह है कि आपको एक या दो (यदि आप कभी तत्वों को मिटाते हैं) मूल्यों को विभाजित करने की आवश्यकता होती है और उन का उपयोग कभी न करें। कुछ मामलों में यह करना आसान है, जैसे कि नकारात्मक स्याही या उस तरह, लेकिन अन्य मामलों में ऐसा नहीं है।
20

3
क्या आज आप इस सिफारिश से खड़े होंगे?
einpoklum

11

C या C ++ में कौन सी लाइब्रेरीज़ में डेटा संरचना होती है जो इस उपयोग के मामले में फिट होती है? या, आप अपने खुद के निर्माण की सिफारिश कैसे करेंगे? धन्यवाद!

LGPL'd जूडी सरणियों की जाँच करें । कभी भी खुद का इस्तेमाल नहीं किया, लेकिन मुझे कुछ अवसरों पर विज्ञापन दिया गया था।

आप STL कंटेनर (std :: hash_map, आदि) को बेंचमार्क करने का भी प्रयास कर सकते हैं। प्लेटफ़ॉर्म / कार्यान्वयन और स्रोत कोड ट्यूनिंग (प्रचारक जितना आप गतिशील मेमोरी प्रबंधन महंगा है) के आधार पर वे पर्याप्त प्रदर्शन कर सकते हैं।

इसके अलावा, यदि अंतिम समाधान का प्रदर्शन समाधान की लागत को कम कर देता है, तो आप सिस्टम को पर्याप्त रैम के साथ आदेश देने का प्रयास कर सकते हैं ताकि सब कुछ सीधे मैदान में रखा जा सके। सूचकांक द्वारा पहुंच का प्रदर्शन अपराजेय है।

ऐड / डिलीट ऑपरेशंस बहुत ज्यादा (100x) ऑपरेशन से ज्यादा लगातार होते हैं।

संकेत है कि आप पहले एल्गोरिदम में सुधार पर ध्यान केंद्रित करना चाहते हो सकता है। यदि डेटा केवल लिखा हुआ है, पढ़ा नहीं गया है, तो उन्हें बिल्कुल क्यों लिखें?


11

बस डिफ़ॉल्ट रूप से उपयोग boost::unordered_map(या tr1आदि)। फिर अपना कोड प्रोफाइल करें और देखें कि क्या वह कोड अड़चन है। तभी मैं तेजी से स्थानापन्न खोजने के लिए आपकी आवश्यकताओं का सटीक विश्लेषण करने का सुझाव दूंगा।


15
यह है। VS2013 का std::unordered_mapमेरे पूरे निष्पादन समय में 90 +% का समय लग रहा है, भले ही मैं प्रसंस्करण के अपेक्षाकृत छोटे हिस्से के लिए मानचित्रों का उपयोग करता हूं।
कैमरन

6

यदि आपके पास एक मल्टीथ्रेडेड प्रोग्राम है, तो आप इंटेल थ्रेड बिल्डिंग ब्लॉक्स लाइब्रेरी में कुछ उपयोगी हैश टेबल पा सकते हैं । उदाहरण के लिए, tbb :: concurrent_unordered_map में समान एपीडी std :: unordered_map है, लेकिन यह मुख्य कार्य थ्रेड सुरक्षित हैं।

इसके अलावा facebook की मूर्खतापूर्ण लाइब्रेरी पर एक नज़र डालें , इसमें उच्च प्रदर्शन समवर्ती हैश तालिका और स्किप सूची है



3

Android स्रोतों से (इस प्रकार Apache 2 लाइसेंस प्राप्त)

https://github.com/CyanogenMod/android_system_core/tree/ics/libcutils

hashmap.c को देखें, इसमें शामिल करें / cutils / hashmap.h, यदि आपको थ्रेड सुरक्षा की आवश्यकता नहीं है तो आप mutex कोड निकाल सकते हैं, एक नमूना कार्यान्वयन libcutils / str_parms.c में है


2

पहले जांचें कि क्या libmemcache जैसे मौजूदा समाधान आपकी आवश्यकता के अनुरूप हैं।

अगर नहीं ...

हैश मानचित्र आपकी आवश्यकता का निश्चित उत्तर प्रतीत होता है। यह कुंजियों के आधार पर ओ (1) लुकअप प्रदान करता है। अधिकांश एसटीएल पुस्तकालय इन दिनों किसी प्रकार का हैश प्रदान करते हैं। इसलिए अपने प्लेटफॉर्म द्वारा दिए गए एक का उपयोग करें।

एक बार जब वह भाग पूरा हो जाता है, तो आपको यह देखने के लिए समाधान का परीक्षण करना होगा कि क्या डिफ़ॉल्ट हैशिंग एल्गोरिथ्म आपकी आवश्यकताओं के लिए पर्याप्त अच्छा प्रदर्शन है।

यदि ऐसा नहीं है, तो आपको नेट पर पाए जाने वाले कुछ अच्छे फास्ट हैशिंग एल्गोरिदम का पता लगाना चाहिए

  1. अच्छा पुराना प्राइम नंबर गुणा अलग
  2. http://www.azillionmonkeys.com/qed/hash.html
  3. http://burtleburtle.net/bob/
  4. http://code.google.com/p/google-sparsehash/

यदि यह पर्याप्त अच्छा नहीं है, तो आप अपने द्वारा हैशिंग मॉड्यूल को रोल कर सकते हैं, जो आपके द्वारा परीक्षण किए गए STL कंटेनरों के साथ देखी गई समस्या को ठीक करता है, और ऊपर हैशिंग एल्गोरिदम में से एक। कहीं न कहीं परिणाम अवश्य देखें।

ओह, और यह दिलचस्प है कि आपके पास कई नक्शे हैं ... शायद आप अपनी कुंजी को 64 बिट के रूप में सरल बना सकते हैं क्योंकि उच्च बिट्स के साथ उपयोग किया जाता है जो यह बताता है कि यह किस मैप से संबंधित है और एक विशाल हैश में सभी प्रमुख मूल्य जोड़े जोड़ते हैं। मैंने हैश देखा है कि मूल प्राइम संख्या हैशिंग एल्गोरिथ्म पर पूरी तरह से अच्छी तरह से काम कर रहे सौ हजार या इतने प्रतीक हैं।

आप सैकड़ों मानचित्रों की तुलना में इस बात की जांच कर सकते हैं कि यह समाधान कैसे प्रदर्शित होता है .. मुझे लगता है कि यह मेमोरी प्रोफाइलिंग दृष्टिकोण से बेहतर हो सकता है ... कृपया इस अभ्यास को करने के लिए परिणाम कहीं पोस्ट करें

मेरा मानना ​​है कि हैशिंग एल्गोरिथ्म से अधिक यह मेमोरी के निरंतर जोड़ने / हटाने (इसे टाला जा सकता है?) और सीपीयू कैश उपयोग प्रोफ़ाइल हो सकती है जो आपके आवेदन के प्रदर्शन के लिए अधिक महत्वपूर्ण हो सकती है।

सौभाग्य


2

विविध कंटेनर टेम्पलेट्स से हैश टेबल आज़माएं । यह closed_hash_mapGoogle के समान गति के बारे में है dense_hash_map, लेकिन उपयोग करने के लिए आसान है (निहित मूल्यों पर कोई प्रतिबंध नहीं है) और कुछ अन्य भत्ते भी हैं।


2

मैं सुझाव दूंगा । बस #include "uthash.h"फिर UT_hash_handleसंरचना में एक जोड़ें और कुंजी के रूप में कार्य करने के लिए अपनी संरचना में एक या अधिक फ़ील्ड चुनें। यहाँ प्रदर्शन के बारे में एक शब्द ।


1

http://incise.org/hash-table-benchmarks.html जीसीसी में बहुत अच्छा कार्यान्वयन है। हालाँकि, मन है कि इसे बहुत खराब मानक निर्णय का सम्मान करना चाहिए:

यदि कोई पुनरावृत्ति होती है, तो सभी पुनरावृत्तियों को अमान्य कर दिया जाता है, लेकिन व्यक्तिगत तत्वों के संदर्भ और संकेत मान्य रहते हैं। यदि कोई वास्तविक पुनर्वसन नहीं होता है, तो कोई परिवर्तन नहीं होता है।

http://www.cplusplus.com/reference/unordered_map/unordered_map/rehash/

इसका मतलब मूल रूप से मानक कहता है कि कार्यान्वयन आवश्यक सूचियों के आधार पर होना चाहिए। यह खुले पते को रोकता है जिसमें बेहतर प्रदर्शन होता है।

मुझे लगता है कि Google स्पार्स खुले पते का उपयोग कर रहा है, हालांकि इन बेंचमार्क में केवल घने संस्करण प्रतियोगिता को बेहतर बनाते हैं। हालांकि, विरल संस्करण स्मृति उपयोग में सभी प्रतियोगिता को बेहतर बनाता है। (यह भी कोई पठार, तत्वों की शुद्ध सीधी रेखा wrt संख्या नहीं है)


1
इसे भी देखें , जो इस बात पर चर्चा करता है कि बाल्टी इंटरफ़ेस को भी कैसे चैनिंग की आवश्यकता है। संदर्भों के बारे में बात बहुत अच्छी है। यह बहस करने के लिए लुभावना है और यह एक उपयोगी गारंटी है, लेकिन कई मामलों में हम केवल फिर से तत्वों को देखने से बचने के लिए संदर्भ चाहते हैं, और सामान्य कारण है क्योंकि लुकअप बहुत धीमा है ... जो कि ऐसा नहीं होगा। संदर्भों को वैध रखना है और इसलिए खुले पते का उपयोग कर सकते हैं! तो यह थोड़ा मुर्गी और अंडा लगता है। यह 2003 के प्रस्ताव का हवाला देते हुए स्पष्ट रूप से चुनाव पर चर्चा करता है।
अंडरस्कोर_ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.