.net 2

2008-10-24 9 views
6

में एक अद्वितीय सेट उत्पन्न करने का सबसे तेज़ तरीका क्या है मेरे पास अनिवार्य रूप से नाम मूल्य जोड़े की एक जंजीर सरणी है - मुझे इससे अद्वितीय नाम मानों का एक सेट उत्पन्न करने की आवश्यकता है। जालीदार सरणी लगभग 86,000 x 11 मान है। इससे कोई फर्क नहीं पड़ता कि मुझे नाम मूल्य जोड़ी (एक एकल स्ट्रिंग "नाम = मान" या उदाहरण के लिए एक विशेष श्रेणी उदाहरण के लिए कुंजीवैलपेयर) स्टोर करना है।
अतिरिक्त जानकारी: 40 अलग-अलग नाम और विशिष्ट मूल्यों की एक बड़ी संख्या है - शायद 10,000 मूल्यों में।.net 2

मैं सी # और .NET 2.0 का उपयोग कर रहा हूं (और प्रदर्शन इतना खराब है कि मैं सोच रहा हूं कि मेरे पूरे जाग वाले सरणी को एक एसक्यूएल डेटाबेस में धक्का देना बेहतर होगा और वहां से एक विशिष्ट चयन करें)।

नीचे वर्तमान कोड इम उपयोग कर रहा है:

List<List<KeyValuePair<string,string>>> vehicleList = retriever.GetVehicles(); 
this.statsLabel.Text = "Unique Vehicles: " + vehicleList.Count; 

Dictionary<KeyValuePair<string, string>, int> uniqueProperties = new Dictionary<KeyValuePair<string, string>, int>(); 
foreach (List<KeyValuePair<string, string>> vehicle in vehicleList) 
{ 
    foreach (KeyValuePair<string, string> property in vehicle) 
    { 
     if (!uniqueProperties.ContainsKey(property)) 
     { 
      uniqueProperties.Add(property, 0); 
     } 
    } 
} 
this.statsLabel.Text += "\rUnique Properties: " + uniqueProperties.Count; 
+0

क्या आप डेटा की तरह दिखने पर कुछ और उदाहरण दे सकते हैं? मुझे यकीन नहीं है कि मैं समझता हूं कि आप यहां क्या करने की कोशिश कर रहे हैं। क्या आप चाबियाँ, या जोड़े पर एक सेट चाहते हैं? –

+0

मै मैट के साथ हूं - मुझे समझ में नहीं आता है कि जहां जालीदार सरणी आती है। इनपुट डेटा दिखाने वाला कुछ नमूना कोड वास्तव में आसान होगा। –

+0

अपनी जंजीर सरणी में, क्या नाम और मूल्यों के बीच कई सहसंबंधों में से कई हैं? क्या आप आउटपुट के रूप में एक से एक सहसंबंध या एक से अधिक सहसंबंध प्राप्त करने की कोशिश कर रहे हैं (फिर मूल्यों के नाम)? यदि आप इसका उत्तर दे सकते हैं, तो मैं एक बेहतर गठित उत्तर प्रदान कर सकता हूं। –

उत्तर

12

मैं इसे 9+ मिनट

समस्या है जब KeyValuePair structs तुलना कर रहा है से नीचे 0.34 सेकंड में चल रहा है। मैंने एक तुलनात्मक वस्तु लिखकर और शब्दकोश के उदाहरण को पास करके इसके आसपास काम किया।

जो मैं निर्धारित कर सकता हूं, से KeyValuePair.GetHashCode() Key ऑब्जेक्ट (इस उदाहरण में कम से कम अद्वितीय ऑब्जेक्ट) का हैशकोड देता है।

चूंकि शब्दकोश प्रत्येक आइटम को जोड़ता है (और अस्तित्व की जांच करता है), यह इक्वाल्स और गेटहाशकोड फ़ंक्शंस दोनों का उपयोग करता है, लेकिन हैशकोड कम अद्वितीय होने पर समान कार्यों पर भरोसा करना पड़ता है।

एक और अद्वितीय गेटहाशकोड फ़ंक्शन प्रदान करके, यह बराबर फ़ंक्शन को बहुत कम करता है। मैंने कम unqiue कुंजी से पहले अधिक अद्वितीय मानों की तुलना करने के लिए समान कार्यों को अनुकूलित किया। 10,000 अद्वितीय गुणों के साथ

86.000 * 11 आइटम नीचे comparer वस्तु का उपयोग कर

आशा इस मदद करता है :)

class StringPairComparer 
     : IEqualityComparer<KeyValuePair<string, string>> 
    { 
     public bool Equals(KeyValuePair<string, string> x, KeyValuePair<string, string> y) 
     { 
      return x.Value == y.Value && x.Key == y.Key; 
     } 
     public int GetHashCode(KeyValuePair<string, string> obj) 
     { 
      return (obj.Key + obj.Value).GetHashCode(); 
     } 
    } 

(comparer वस्तु यह 9 मिनट 22 सेकंड लेता है) के बिना 0.34 सेकंड में चलाता है संपादित करें: यदि यह केवल एक स्ट्रिंग था (एक KeyValuePair के बजाय, जहां स्ट्रिंग = नाम + मान) यह लगभग दोगुना तेज़ होगा। यह एक अच्छी घुसपैठ की समस्या है, और मैंने पर खर्च किया है (मैंने थोड़ा सा शांत सीखा)

0

अगर आप प्रत्येक मुख्य/मान जोड़े और अनन्य मानों आप जेनरेट कर रहे हैं, तो आप सिर्फ एक GUID इस्तेमाल कर सकते हैं के बीच किसी भी विशिष्ट सहसंबंध की जरूरत नहीं है? मुझे लगता है कि समस्या यह है कि आपकी वर्तमान 'कुंजी' इस जालीदार सरणी में अद्वितीय नहीं है।

Dictionary<System.Guid, KeyValuePair<string, string>> myDict 
    = new Dictionary<Guid, KeyValuePair<string, string>>(); 


foreach of your key values in their current format 
    myDict.Add(System.Guid.NewGuid(), new KeyValuePair<string, string>(yourKey, yourvalue)) 

ऐसा लगता है कि यह स्टोर हैं कि तुम क्या जरूरत है, लेकिन मैं वहाँ के रूप में उत्पन्न Guid & क्या आप मूल रूप से था ...

के बीच कोई अर्थ संबंध होगा पता नहीं कैसे आप इस से वापस डेटा खींच जाएगा

क्या आप अपने प्रश्न में और जानकारी प्रदान कर सकते हैं?

0

एक रैपर वर्ग के रूप में KeyValuePair का उपयोग करें और फिर शायद एक सेट बनाने के लिए एक शब्दकोश बनाएँ? या अपने स्वयं के रैपर को लागू करें जो बराबर और GetHashCode को ओवरराइड करता है।

Dictionary<KeyValuePair, bool> mySet; 

for(int i = 0; i < keys.length; ++i) 
{ 
    KeyValuePair kvp = new KeyValuePair(keys[i], values[i]); 
    mySet[kvp] = true; 
} 
0
बजाय एक Dictionary का उपयोग करने का

क्यों नहीं KeyedCollection<TKey, TItem> का विस्तार? प्रलेखन के अनुसार:

एक संग्रह के लिए सार आधार वर्ग प्रदान करता है जिनकी चाबियाँ मानों में एम्बेडेड होती हैं।

आपको protected TKey GetKeyForItem(TItem item) फ़ंक्शन को ओवरराइड करने की आवश्यकता है। चूंकि यह IList<T> और IDictionary<TKey, TValue> के बीच एक संकर है, मुझे लगता है कि यह काफी तेज होने की संभावना है।

0

के बारे में कैसे:

Dictionary<NameValuePair,int> hs = new Dictionary<NameValuePair,int>(); 
foreach (i in jaggedArray) 
{ 
    foreach (j in i) 
    { 
     if (!hs.ContainsKey(j)) 
     { 
      hs.Add(j, 0); 
     } 
    } 
} 
IEnumerable<NameValuePair> unique = hs.Keys; 
निश्चित रूप से

, यदि आप सी # 3.0 उपयोग कर रहे थे, .NET 3.5:

var hs = new HashSet<NameValuePair>(); 
hs.UnionWith(jaggedArray.SelectMany(item => item)); 

चाल करना होगा।

+0

यह लगभग बिल्कुल सही कोड है जिसका मैं वर्तमान में उपयोग कर रहा हूं - दुर्भाग्य से लगभग 20 मिनट के बाद मुझे अधीर हो जाता है और एप्लिकेशन को मार दिया जाता है। – dice

+0

सी # 3 में आप केवल 'डिस्टिंक()' का उपयोग कर सकते हैं। –

+0

@ कोनराड रुडॉल्फ: हाँ, और यह उतना ही धीमा होगा। –

0

क्या आपने अपना कोड प्रोफाइल किया है? आप निश्चित हैं कि foreach loops बाधा हैं, और retriever नहीं। GetVehicles()?

मैंने एक छोटा परीक्षण प्रोजेक्ट बनाया जहां मैं प्रतिद्वंद्वी को नकली बना देता हूं और इसे 86,000 एक्स 11 मान देता हूं। मेरा पहला प्रयास 5 सेकंड में चला गया, जिसमें डेटा शामिल था।

मैंने कुंजी और मूल्य दोनों के लिए समान मूल्य का उपयोग किया जहां पहली कुंजी "0 # 0" और अंतिम "85 999 # 10" थी।

फिर मैंने guids पर स्विच किया। वही परिणाम

तब मैं कुंजी अब, इस तरह बनाया:

 var s = Guid.NewGuid().ToString(); 
     return s + s + s + s + s + s + s+ s + s + s; 

अब यह लगभग 10 सेकंड लिया।

तब मैंने चाबियाँ बहुत लंबे समय तक बनाई और मेमोरी अपवाद से बाहर हो गया। मेरे कंप्यूटर पर एक स्वैप फ़ाइल नहीं है, इसलिए मुझे यह अपवाद तुरंत मिला।

आपकी चाबियाँ कब तक हैं? क्या आपकी वर्चुअल मेमोरी खपत आपके खराब प्रदर्शन का कारण है?

+0

GetVehicles() मेरे मामले में काफी तेज़ है - मुझे लगता है कि अंतर डेटा है - आपके डेटा में सभी अद्वितीय मूल्य होंगे जबकि मेरा नहीं होगा - फिर भी यह आश्चर्यजनक है कि यह आपके लिए कितनी तेजी से चलता है। यह बाहरी पाश में 86,000 और आंतरिक में 11 होना चाहिए। – dice

संबंधित मुद्दे