38

मैं यह निर्धारित करने की कोशिश कर रहा हूं कि कितनी धीमी इकाई फ्रेमवर्क संग्रहित प्रक्रियाओं पर है। मुझे उम्मीद है कि विकास के आसानी के लिए हमें इकाई फ्रेमवर्क का उपयोग करने के लिए अपने मालिक को मनाने की उम्मीद है।इकाई फ्रेमवर्क बनाम संग्रहीत प्रक्रियाएं - प्रदर्शन उपाय

समस्या यह है कि मैंने एक प्रदर्शन परीक्षण चलाया और ऐसा लगता है कि ईएफ संग्रहीत प्रक्रियाओं की तुलना में लगभग 7 गुना धीमी है। मुझे विश्वास करना बेहद मुश्किल लगता है, और मैं सोच रहा हूं कि मुझे कुछ याद आ रहा है या नहीं। क्या यह एक निर्णायक टेस्ट है? क्या ईएफ टेस्ट के प्रदर्शन को बढ़ाने के लिए मैं कुछ भी कर सकता हूं?

 var queries = 10000; 

     // Stored Proc Test 
     Stopwatch spStopwatch = new Stopwatch(); 
     spStopwatch.Start(); 
     for (int i = 0; i < queries; i++) 
     { 
      using (var sqlConn = new SlxDbConnection().Connection) 
      { 
       var cmd = new SqlCommand("uspSearchPerformanceTest", sqlConn) { CommandType = CommandType.StoredProcedure }; 

       cmd.Parameters.AddWithValue("@searchText", "gstrader"); 
       sqlConn.Open(); 
       SqlDataReader dr = cmd.ExecuteReader(); 

       List<User> users = new List<User>(); 
       while (dr.Read()) 
       { 
        users.Add(new User 
        { 
         IsAnonymous = Convert.ToBoolean(dr["IsAnonymous"]), 
         LastActivityDate = Convert.ToDateTime(dr["LastActivityDate"]), 
         LoweredUserName = dr["LoweredUserName"].ToString(), 
         MobileAlias = dr["MobileAlias"].ToString(), 
         UserId = new Guid(dr["UserId"].ToString()), 
         UserName = (dr["UserName"]).ToString() 
        }); 
       } 

       var username = users.First().UserName; 
       sqlConn.Close(); 
      } 
     } 
     spStopwatch.Stop(); 
     Console.WriteLine("SP - {0} Queries took {1}", queries, spStopwatch.ElapsedMilliseconds); 

     // EF Test 
     Stopwatch entityStopWatch = new Stopwatch(); 

     var context = new SlxDbContext(); 
     var userSet = context.Set<User>(); 
     entityStopWatch.Start(); 
     for (int i = 0; i < queries; i++) 
     { 
      User user = userSet.Where(x => x.UserName == "gstrader").First(); 
     } 

     entityStopWatch.Stop(); 
     Console.WriteLine("Entity - {0} Queries took {1}", queries, entityStopWatch.ElapsedMilliseconds); 

परिणाम:

सपा - 10000 प्रश्नों 2278

इकाई ले गया - 10000 प्रश्नों 16277

+0

मैं जोड़ना चाहता हूं कि स्पष्ट रूप से कनवर्ट करने के बजाय उस अनबॉक्सिंग को पर्याप्त होना चाहिए। तो करें: (स्ट्रिंग) डॉ ["मोबाइलअलीअस"] के बजाय। टोस्टरिंग() – Alex

उत्तर

52

ले लिया वहाँ कुछ चीजें आप कर सकते हैं आपकी क्वेरी अनुकूलन करने के लिए कर रहे हैं। Here on MSDN आप एक अच्छा अवलोकन देख सकते हैं।

लेकिन ईमानदार होने के लिए, मैन्युअल मानचित्रण के साथ एक संग्रहीत प्रक्रिया हमेशा प्रदर्शन में तेज होगी। लेकिन खुद से पूछें, प्रदर्शन कितना महत्वपूर्ण है? अधिकांश परियोजनाओं में, विकास का समय प्रदर्शन के बाद और अधिक महत्वपूर्ण है। विकसित करना मुश्किल था? पार्सिंग या इकाई फ्रेमवर्क क्वेरी के साथ कच्ची क्वेरी?

ओआरएम डिज़ाइन नहीं किए गए हैं क्योंकि वे हाथ से लिखित दृष्टिकोण से बहुत बेहतर प्रदर्शन करते हैं। हम उनका उपयोग करते हैं क्योंकि विकास इतना आसान है!

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

+11

आपके उपयोगकर्ता आपसे असहमत होंगे कि डेवलपर का समय उनके मुकाबले ज्यादा महत्वपूर्ण है ... खासकर जब वे उस कताई घंटे का चश्मा देख रहे हैं! उस ने कहा, क्यों स्प्रेक्स में एसक्यूएल नहीं लिखते हैं और उन्हें ईएफ का उपयोग करके बुलाते हैं - दोनों दुनिया के सर्वश्रेष्ठ? – gbjbaanb

+19

यदि आपके पास कताई घंटे का चश्मा है तो आपके पास एक असली परिदृश्य है जिसे आप अनुकूलित कर सकते हैं। उस परिदृश्य को पाने के लिए डेवलपर उत्पादकता मेरी राय में अधिक महत्वपूर्ण है, इसलिए समयपूर्व ऑप्टिमाइज़ेशन –

+1

मैं रिपोजिटरी पैटर्न के एक पुनर्विक्रय उदाहरण के बारे में वर्षों से सोच रहा था। अब मेरे पास है। धन्यवाद :) –

6

@ वाउटर डी कॉर्ट के साथ समझौते में ... इसके अलावा, जब आपको प्रक्रियाओं में स्थानांतरित करने की आवश्यकता होती है, तो आप एक से दूसरे में माइग्रेशन की सहायता के लिए प्रक्रियाओं के संयोजन के साथ ईएफ का उपयोग कर सकते हैं।

यदि आप अच्छी तरह से डिज़ाइन की गई प्रक्रियाओं में कार्यक्षमता को एकीकृत करते हैं तो प्रक्रियाओं में आगे बढ़ना एक सामान्य अनुप्रयोग में तेज़ होगा। यानी एक जितना संभव हो उतना कॉल करें जितना संभव हो उतना काम करें। उदाहरण के लिए, यदि कोई उपयोगकर्ता चेक-आउट बटन पर क्लिक करता है जब खरीदारी की टोकरी MVC अनुप्रयोग में, आप ORM की तरह कुछ करने के लिए उपयोग कर सकते हैं: (? लॉगिन अभी भी मान्य है)

  1. एक उपयोगकर्ता के प्रमाणीकरण को देखने
  2. अनुमतियों को देखने के (उन्होंने कहा कि खरीद सकते हैं आइटम ?, वहाँ विशेष आवश्यकताओं हैं?)
  3. शेयर मात्रा देखो सुनिश्चित करने के लिए वे इस प्रक्रिया में समाप्त नहीं कर रहे थे डीबी को
  4. लिखने (उपलब्ध सूची से निकालने के लिए) आइटम आरक्षण भुगतान से पहले
  5. loo के ऊपर भुगतान जानकारी
  6. लॉगिंग ...?

या यह पूरी तरह से अलग कदम हो सकता है, लेकिन किसी भी मामले में, बिंदु यह है कि एमवीसी ऐप अगले चरण में जाने के लिए डीबी को कई कॉल करने के लिए ओआरएम का उपयोग करेगा।

यदि यह सब तर्क एक अच्छी तरह लिखित स्पोक में encapsulated है तो sproc के लिए केवल एक कॉल है और आप कर रहे हैं। एमवीसी-ओआरएम मार्ग के साथ डेटा को डीबी से चालक में कॉपी किया जाना चाहिए और ओआरएम (आमतौर पर नेट पर एक अलग मेजबान पर) पर पहुंचाया जाना चाहिए और फिर एक सरल निर्णय लेने के लिए एमवीसी ऐप द्वारा पढ़ा जाना चाहिए जब तक कि सभी चरणों को पूरा नहीं किया जाता । एक स्पोक का उपयोग करने के मामले में जो चेक-आउट चरण को समाहित करता है, वहां बहुत कम डेटा कॉपी करने और आगे बढ़ने के लिए, कम नेटवर्क आईओ, कम संदर्भ स्विचिंग आदि

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

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

यह कहना नहीं है कि यह आवश्यक है बेहतर। निर्णय से तथ्यों को अलग करने का मतलब है कि ये घटक अलग-अलग प्रतिस्थापन योग्य/टेस्टेबल हैं, हालांकि, यदि आप अपने एमवीसी और आपके डीबी से विवाहित हैं तो यह एक "गैर-मुद्दा" है।

दूसरी ओर कई एमवीसी प्रशंसकों को एसक्यूएल लिखने से नफरत है ताकि वे एक प्राकृतिक आपदा के रूप में एसक्यूएल में कोई निर्णय तर्क डालने पर विचार करें। ऐसे लोगों के लिए में एक ही तर्क लिखा जाना आवश्यक है कि एमवीसी का उपयोग करता है क्योंकि यह उनके लिए विकास को गति देता है। कुछ मामलों में यह कुछ "आरडीएमबीएस" के मामले में भी "गैर-मुद्दा" है, आप उसी भाषा में स्पॉक्स लिख सकते हैं जैसा कि एमवीसी द्वारा उपयोग किया जाता है (उदाहरण: .NET - SQL सर्वर स्पॉक्स सी # में उपयोग किए जा सकते हैं और उपयोग .Net; Postgresql फ़ंक्शंस (कोई sprocs) पर्ल, पायथन, PHP et। Al में लिखा जा सकता है) इस मामले में लाभ यह है कि आपके पास तेजी से स्पॉक्स हो सकते हैं जो एक कॉल में कई चरणों को समाहित करता है और आप प्रोग्रामिंग भाषा का उपयोग कर सकते हैं कोडिंग में पहले से ही जल्दी हैं।

+2

मैंने एक बार स्पॉक्स के लिए सी # का उपयोग किया .. भयानक प्रदर्शन। एसक्यूएल काफी तेज था।मुझे लगता है कि इसे प्रबंधित-> अप्रबंधित संक्रमणों के साथ कुछ करना था, लेकिन किसी भी तरह से: नौकरी के लिए सही उपकरण का उपयोग करें, न कि "सी # हथौड़ा" – gbjbaanb

+0

यदि प्रदर्शन अनिवार्य है और आपको सी ++ लिखना बुरा नहीं लगता है तो आप लिख सकते हैं सी ++ में विस्तारित संग्रहीत प्रक्रियाओं को (यदि सही किया गया हो) कुछ और हराया जाना चाहिए और यह # से अधिक असाधारण रूप से दुबला होगा –