2013-03-12 8 views
12

मैंने लिंक के इस टुकड़े को एक क्रॉस करने के लिए लिखा है, एक डेटाबेस की तरह जुड़ें कई सूचियों के बीच होगा।यह क्रॉस लिंक में इतना धीमा क्यों है?

लेकिन कुछ कारणों से यह बहुत धीमी है जब कोई भी सूची 3000 से अधिक हो जाती है। मैं 30 के लिए इंतजार करूँगा? ये सूचियां बहुत बड़ी संख्या में जा सकती हैं।

इस क्वेरी से आ रही ColumnDataIndex अन्य सूची के डेटा के साथ प्रत्येक रिश्ते के लिए लूप में चलाया जाता है।

कोई सलाह?

अद्यतन ** - डेटा सामान्य सूचियों में डाला गया है जो कॉन्फ़िगर किए गए स्रोतों से पहले बनाए गए हैं। इस समय यह सब स्मृति में है।

RunningResult[parameter.Uid] = (from source_row in RunningResult[parameter.Uid] 
          from target_row in ColumnDataIndex[dest_key] 
          where GetColumnFromUID(source_row, rel.SourceColumn) == GetColumnFromUID(target_row, rel.TargetColumn) 
          select new Row() 
          { 
           Columns = MergeColumns(source_row.Columns, target_row.Columns) 

          }).ToList(); 

2 अतिरिक्त कार्य:

MergeColumns: 2 आइटम से कॉलम ले जाता है और उन्हें एक ही सरणी में विलीन हो जाती है।

public static Columnn[] MergeColumns(Column[] source_columns, Column[] target_columns) 
{ 
     Provider.Data.BucketColumn[] new_column = new Provider.Data.BucketColumn[source_columns.Length + target_columns.Length]; 
     source_columns.CopyTo(new_column, 0); 
     target_columns.CopyTo(new_column, source_columns.Length); 
     return new_column; 
    } 

GetColumnFromUID: रिटर्न दिए गए स्तंभ uid मिलान मद में स्तंभ का मान।

private static String GetColumnFromUID(Row row, String column_uid) 
    { 
     if (row != null) 
     { 
      var dest_col = row.Columns.FirstOrDefault(col => col.ColumnUid == column_uid); 
      return dest_col == null ? "" + row.RowId : dest_col.Value.ToString().ToLower(); 
     } 
     else return String.Empty; 

    } 

अद्यतन:

डेटा और एक डेटाबेस के लिए क्वेरी चलती समाप्त हो गया। यह गति को कई एमएस तक कम कर दिया गया। एक अनुकूलित looped समारोह लिखा हो सकता है, लेकिन यह मेरे लिए सबसे तेज़ तरीका था।

+0

आप कहाँ अपने datasources परिभाषित कर रहे हैं, के अंदर या लूप के बाहर:

LINQ अपने स्वयं के आंतरिक आपरेशन, Join में शामिल होने है, तो आप भी अपने खुद के बारे में की जरूरत नहीं है नहीं है।यदि बाहर हैं, तो वे क्वेरी करने योग्य स्रोत या सूचियां हैं। –

+0

मैं उन्हें –

+11

से ऊपर लूप के बाहर बना रहा हूं मेरी सलाह: ** एक प्रोफाइलर चलाएं। ** कुछ और अनुमान लगा रहा है। –

उत्तर

4

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

RunningResult[parameter.Uid] = (from source_row in RunningResult[parameter.Uid] 
           join target_row in ColumnDataIndex[dest_key] 
           on GetColumnFromUID(source_row, rel.SourceColumn) equals 
            GetColumnFromUID(target_row, rel.TargetColumn) 
           select new Row() 
           { 
            Columns = MergeColumns(source_row.Columns, target_row.Columns) 

           }).ToList(); 
+0

इस क्वेरी को डेटाबेस में ले जाने का अंत हो गया, लेकिन जब मैंने इसका परीक्षण किया था तो इस जवाब ने क्वेरी को तेज कर दिया था। –

0

आप एक क्रॉस जॉइन नहीं कर रहे हैं, लेकिन एक आंतरिक धारा, केवल आपके मामले में, जहां अनुमान लगाया गया है, पर एक खंड शामिल है।

एक भीतरी शामिल होने के लिए आम तौर पर, दो हैश सेट/तालिकाओं के साथ किया जाता है, ताकि आप जल्दी से पंक्ति वाई में मूल्य के आधार पर सेट एक्स में पंक्ति पा सकते हैं

तो 'वेस्टन के जवाब ठीक है, फिर भी आप की जरूरत है इसे वास्तव में तेज़ बनाने के लिए शब्दकोश/हैशटेबल्स का उपयोग करें। ध्यान रखें कि प्रति कुंजी अधिक पंक्तियां हो सकती हैं। आप इसके लिए एक बहु-मूल्य हैशटेबल/शब्दकोश का उपयोग कर सकते हैं: https://github.com/SolutionsDesign/Algorithmia/blob/master/SD.Tools.Algorithmia/GeneralDataStructures/MultiValueDictionary.cs

+1

वह वास्तव में एक क्रॉस जॉइन कर रहा है। उन्हें केवल एक * शामिल करने की जरूरत है, एक आंतरिक जुड़ाव करने के लिए, उसका उदाहरण दिया गया है, और आंतरिक जुड़ाव करने से प्रदर्शन में काफी सुधार होगा। तथ्य यह है कि वह एक क्रॉस कर रहा है ताकि आंतरिक परिणाम में समान परिणाम प्राप्त हो सकें, प्रदर्शन समस्याओं का कारण है। ध्यान दें कि LINQ में 'जॉइन' ऑपरेटर है जिसे वह आंतरिक जुड़ने के लिए उपयोग कर सकता है; उसे करने के लिए उसे अपनी हैश टेबल बनाने की आवश्यकता नहीं है (हालांकि वह निश्चित रूप से कर सकता था)। – Servy

+0

मैंने अभी उदाहरण को देखा, और कुछ नहीं। उदाहरण यह करता है: चुनें ... एक्स से, वाई जहां X.field = Y.field; वही चीज। से .. खंडों से वास्तव में एक क्रॉस में शामिल होने का संकेत दिया जाएगा, फिर भी जहां खंड इसे अर्थात् क्रॉस में शामिल नहीं करता है। या बेहतर: निर्माण से उसका प्रश्न ... निर्माण से वह जो करना चाहता है उसके लिए इष्टतम नहीं है। मुझे पता है कि लिंक में एक ऑपरेटर शामिल है, मेरा विश्वास करो;) –

+0

तथ्य यह है कि वह एक SelectMany का उपयोग करता है जिसके बाद इसका मतलब है कि वह वास्तव में एक क्रॉस जॉइन कर रहा है। यह एक SelectMany * की परिभाषा है जो 'से एक्स से एक्स ... 'मानचित्र है। वह एक क्रॉस में शामिल हो रहा है और फिर परिणामों को फ़िल्टर कर रहा है कि आंतरिक जुड़ने के परिणाम क्या होंगे। शुरुआत से ही जुड़ाव करने के बजाय यह * बहुत * अधिक समय लेने वाला है क्योंकि आप अनियंत्रित ओवरहेड के बहुत से बचते हैं। – Servy

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