2011-11-06 13 views
7

मैं तरीके जितनी जल्दी संभव हो एक एसक्यूएल सर्वर से डेटा को पढ़ने के लिए प्रयोग कर रहे हैं और मैं एक रोचक खोज बारे में जाना। यदि मैं के बजाय List<object[]> में डेटा पढ़ता हूं, तो प्रदर्शन डबल से अधिक बढ़ता है।SqlDataReader प्रदर्शन सूची <string[]> या सूची <object[]>

मुझे लगता है इस खेतों पर ToString() विधि कॉल करने के नहीं होने की वजह से है, लेकिन मैं हमेशा सोचा था कि वस्तुओं का उपयोग कर प्रदर्शन पर नकारात्मक प्रभाव पड़ा।

स्ट्रिंग सरणी के बजाय ऑब्जेक्ट एरे की सूची का उपयोग न करने का कोई कारण है?

संपादित करें: एक विचार मैंने अभी इस डेटा का भंडारण आकार था। ऑब्जेक्ट सरणी में डेटा संग्रहीत करने से तारों की तुलना में अधिक कमरा लगेगा?

private void executeSqlObject() 
    { 
     List<object[]> list = new List<object[]>(); 

     using (SqlConnection cnn = new SqlConnection(_cnnString)) 
     { 
      cnn.Open(); 
      SqlCommand cmd = new SqlCommand("select * from test_table", cnn); 

      SqlDataReader reader = cmd.ExecuteReader(); 

      int fieldCount = reader.FieldCount; 

      while (reader.Read()) 
      { 
       object[] row = new object[fieldCount]; 

       for (int i = 0; i < fieldCount; i++) 
       { 
        row[i] = reader[i]; 
       } 
       list.Add(row); 
      } 
     } 
    } 

    private void executeSqlString() 
    { 
     List<string[]> list = new List<string[]>(); 

     using (SqlConnection cnn = new SqlConnection(_cnnString)) 
     { 
      cnn.Open(); 
      SqlCommand cmd = new SqlCommand("select * from test_table", cnn); 

      SqlDataReader reader = cmd.ExecuteReader(); 

      int fieldCount = reader.FieldCount; 

      while (reader.Read()) 
      { 
       string[] row = new string[fieldCount]; 

       for (int i = 0; i < fieldCount; i++) 
       { 
        row[i] = reader[i].ToString(); 
       } 
       list.Add(row); 
      } 
     } 
    } 

    private void runTests() 
    { 
     Stopwatch watch = new Stopwatch(); 
     for (int i = 0; i < 10; i++) 
     { 
      watch.Start(); 
      executeSqlObject(); 
      Debug.WriteLine("Object Time: " + watch.ElapsedMilliseconds.ToString()); 
      watch.Reset(); 
     } 
     for (int i = 0; i < 10; i++) 
     { 
      watch.Start(); 
      executeSqlString(); 
      Debug.WriteLine("String Time: " + watch.ElapsedMilliseconds.ToString()); 
      watch.Reset(); 
     } 
    } 

और परिणाम::

Object Time: 879 
Object Time: 812 
Object Time: 825 
Object Time: 882 
Object Time: 880 
Object Time: 905 
Object Time: 815 
Object Time: 799 
Object Time: 823 
Object Time: 817 
Average: 844 

String Time: 1819 
String Time: 1790 
String Time: 1787 
String Time: 1856 
String Time: 1795 
String Time: 1731 
String Time: 1792 
String Time: 1799 
String Time: 1762 
String Time: 1869 
Average: 1800 
+1

परिणाम के साथ बहस नहीं कर सकता। आपको बयानों का उपयोग करने में अपने पाठकों (और कमांड भी) को लपेटना चाहिए क्योंकि वे स्मृति को रिसाव कर सकते हैं। –

+0

परीक्षण के साथ कुछ गड़बड़ होनी चाहिए ... डेटाबेस से डेटा पढ़ने की तुलना में, स्ट्रिंग प्रकार की जांच करना * चाहिए * negligigle होना चाहिए। – Guffa

+0

जिज्ञासा से बाहर, क्या आप किसी भी स्ट्रिंग ('पंक्ति [i] = (स्ट्रिंग) पाठक [i]; ') पर पाठक मान को केवल उस पर अलग करते हैं, इसके बजाय' ToString() 'को कॉल करने के बजाय, या इसके बजाय, मूल्य को पुनः प्राप्त करने के लिए अंतर्निहित 'SqlDataReader.GetString()' विधि का उपयोग करके ('पंक्ति [i] = reader.GetString (i);')? (सभी कॉलम मानों को समझना तार हैं।) –

उत्तर

8

object केवल भूमि के ऊपर कहते हैं अगर आप अतिरिक्त मुक्केबाजी उत्पन्न कर रहे हैं

यहाँ अपने परीक्षण कोड है। और फिर भी, यह प्रभाव काफी कम है। आपके मामले में, reader[i]हमेशाobject देता है। आपके पास पहले से ही object है, इससे कोई फर्क नहीं पड़ता कि यह एक स्ट्रिंग, या एक इंट इत्यादि का संदर्भ है, पाठ्यक्रम.ToString() कॉलिंग ओवरहेड जोड़ता है; ज्यादातर मामलों में (int, DateTime, आदि) इसमें फ़ॉर्मेटिंग कोड और दोनों एक (या अधिक) अतिरिक्त स्ट्रिंग का आवंटन शामिल है। string पर बदलकर आप डेटा बदल रहे हैं (बदतर के लिए, आईएमओ - उदाहरण के लिए, आप तारीखों पर सही प्रकार नहीं कर सकते हैं, उदाहरण के लिए) और ओवरहेड जोड़ना। यहां का एज केस यह है कि यदि सभी कॉलम पहले से ही वास्तव में तार हैं - इस मामले में आप केवल कुछ वर्चुअल विधि कॉल जोड़ते हैं (लेकिन कोई अतिरिक्त वास्तविक कार्य नहीं)।

जानकारी के लिए, यदि आप कच्चे प्रदर्शन के बाद हैं, तो मैं सूक्ष्म-ओआरएम जैसे डैपर को देखने की पूरी तरह से अनुशंसा करता हूं। उन्हें अत्यधिक अनुकूलित किया जाता है, लेकिन "पूर्ण" ओआरएम के वजन से बचें। उदाहरण के लिए, व्यवसायिक में के लिए:

var myData = connection.Query<TypedObject>("select * from test_table").ToList(); 

होगा, मैं उम्मीद, प्रदर्शन बहुत तुलनात्मक जब तुम दृढ़ता से टाइप किया वस्तु डेटा दे रही है।

+0

मार्क का उपयोग करने के मुकाबले परिणाम क्या थे, अच्छी जानकारी के लिए धन्यवाद। माइक्रो-ओआरएम समाधान के संदर्भ में, क्या इस समाधान के लिए मुझे डेटासेट को जानने की आवश्यकता नहीं है जिसे मैं क्वेरी निष्पादित करने से पहले पुनर्प्राप्त कर रहा हूं? मुझे इस एप्लिकेशन को – ChandlerPelhams

+0

@ChandlerPelhams को पुनर्प्राप्त करने वाले डेटा के अज्ञेयवादी होने की आवश्यकता है जो प्रश्न से स्पष्ट नहीं था; मान लीजिए कि आप जेनरिक के माध्यम से 'टी' को नीचे नहीं पारित कर सकते हैं (अधिकांश अनुप्रयोगों में, * कॉलर के कुछ * भाग जानता है कि डेटा कैसा दिखता है), फिर वास्तव में कुछ ऑब्जेक्ट जैसे 'ऑब्जेक्ट []' या, "लोड्स" नोट्स, 'डेटाटेबल' के रूप में, अधिक उपयुक्त हो सकता है। –

1

स्ट्रिंग सरणी के बजाय ऑब्जेक्ट एरे की सूची का उपयोग न करने का कोई कारण है?

यह है कि तुम क्या लिया गया मूल्यों से कोई लेना देना जाने के बाद उन्हें विन्यास में मिल गया है, अगर आप तो वस्तुओं की एक सूची होने एक वस्तु के रूप में प्रत्येक मूल्य के इलाज के लिए खुश हैं ठीक है चाहता था पर निर्भर करेगा, लेकिन अगर आप उन्हें तारों के रूप में व्यवहार करना चाहते हैं तो किसी बिंदु पर आपको ऑब्जेक्ट को स्ट्रिंग में कनवर्ट/कस्ट करना होगा ताकि आप कहीं भी लागत ले सकें।

के रूप में कोरी उल्लेख किया है, तो आप SqlDataReader आप GetString (int) विधि का उपयोग कर के बजाय मूल्य पर ToString() कॉल का परीक्षण करना चाहिए, और बेंचमार्क के रूप में उपयोग से एक स्ट्रिंग के रूप मूल्य पढ़ रहे हैं।

वैकल्पिक रूप से, ऐरे का उपयोग करने के बजाय आप डेटासेट में मानों को पढ़ सकते हैं जो बाद में काम करना आसान साबित हो सकता है।

दिन का अंत, सबसे अच्छा क्या है इस पर निर्भर करता है कि आप डेटाबेस से उन्हें पुनर्प्राप्त करने के बाद परिणामों का उपयोग कैसे करना चाहते हैं।

+0

lol, डेटासेट बनाम एरे की सूची की उपयोगिता ... लगता है कि यह एक और एसओ प्रश्न के लिए एक विषय है :) – lowds

+0

@ मार्क - मैं भी :) – ChandlerPelhams

+0

दिए गए मामले में, ऐसा लगता है (टिप्पणियां) कि कोड लेआउट को नहीं जानता , इस मामले में मुझे यह ध्यान रखना होगा कि डेटाटेबल वास्तव में उपयुक्त हो सकता है। –

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