2008-09-28 8 views
6

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

मैं सोच रहा था कि जो भी .NET के डेटासेट क्लास के कार्यान्वयन के बारे में कुछ भी जानता है, वह जो भी जानता है उसे साझा करने की देखभाल करेगा।

मैं कुछ इस तरह करते हैं:

DataTable dt = new DataTable(); 
if(dt.Columns.Contains("SomeColumn")) 
{ 
    object o = dt.Rows[0]["SomeColumn"]; 
} 

कितनी तेजी से देखने समय Contains(...) विधि के लिए, और Object o में स्टोर करने के लिए मूल्य पुन: प्राप्त करने के लिए हो सकता है? मैंने सोचा होगा कि यह हैशटेबल की तरह बहुत तेज है (मान लीजिए कि मैं हैशटेबल्स के बारे में क्या समझता हूं) लेकिन यह ऐसा प्रतीत नहीं होता है ...

मैंने स्मृति से कोड लिखा है, इसलिए कुछ चीजें "वाक्य रचनात्मक रूप से नहीं हो सकती हैं सही बात"।

उत्तर

2

Reflector वाया DataRow [ "columnName"] के लिए कदम हैं:

  1. columnName से DataColumn प्राप्त करें। पंक्ति के DataColumnCollection ["ColumnName"] का उपयोग करता है। आंतरिक रूप से, DataColumnCollection अपने डेटा कॉलम को एक हस्टेबल में संग्रहीत करता है। ओ (1)
  2. डेटारो की पंक्ति अनुक्रमणिका प्राप्त करें। सूचकांक एक आंतरिक सदस्य में संग्रहीत किया जाता है। ओ (1)
  3. डेटाकॉलम [इंडेक्स] का उपयोग कर इंडेक्स पर डेटा कॉलम का मान प्राप्त करें। DataColumn अपने डेटा को System.Data.Common.DataStorage (आंतरिक, सार) सदस्य में संग्रहीत करता है:

    वापसी डेटा कॉलमInstance._storage.Get (recordIndex);

    एक नमूना ठोस कार्यान्वयन System.Data.Common.StringStorage (आंतरिक, मुहरबंद) है। स्ट्रिंगस्टॉरेज (और अन्य कंक्रीट डेटास्टोरेज जिन्हें मैंने चेक किया है) अपने मानों को सरणी में संग्रहीत करते हैं। Get (recordIndex) आसानी से रिकॉर्ड इंडेक्स पर मान सरणी में ऑब्जेक्ट को पकड़ लेता है। ओ (1)

तो कुल मिलाकर आप ओ (1) हैं लेकिन इसका मतलब यह नहीं है कि ऑपरेशन के दौरान हैशिंग और फ़ंक्शन कॉलिंग बिना लागत के है। इसका मतलब यह है कि डेटारो या डेटा कॉलम की संख्या बढ़ने के कारण इसका अधिक खर्च नहीं होता है।

दिलचस्प है कि डेटास्टॉरेज मूल्यों के लिए सरणी का उपयोग करता है।कल्पना नहीं कर सकते कि जब आप पंक्तियां जोड़ते हैं या हटाते हैं तो पुनर्निर्माण करना आसान होता है।

0

मुझे कल्पना है कि कोई भी लुकअप ओ (एन) होगा, क्योंकि मुझे नहीं लगता कि वे किसी भी प्रकार के हैशटेबल का उपयोग करेंगे, लेकिन वास्तव में पंक्तियों और स्तंभों को खोजने के लिए अधिक सरणी का उपयोग करेंगे।

+0

यह ओ (एन^2) होगा क्योंकि आप प्रत्येक आइटम पर स्ट्रिंग तुलना कर रहे हैं। –

0

वास्तव में, मेरा मानना ​​है कि कॉलम नाम हैशटेबल में संग्रहीत हैं। केस-संवेदनशील लुकअप के लिए ओ (1) या निरंतर लुकअप होना चाहिए। अगर इसे प्रत्येक को देखना था, तो निश्चित रूप से यह ओ (एन) होगा।

3

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

const int SomeTable_SomeColumn = 0; 

DataTable dt = new DataTable(); 
if(dt.Columns.Contains(SomeTable_SomeColumn)) 
{ 
    object o = dt.Rows[0][SomeTable_SomeColumn]; 
} 
संबंधित मुद्दे