2013-02-15 31 views
8

मेरे पास एक LINQ प्रश्न था, मुझे आश्चर्य हुआ कि अगर किसी को इसका जवाब पता था।फर्स्टऑर्डडिफॉल्ट/फर्स्ट एंड ऑर्डर बाय डिस्केन्डिंग, LastOrDefault/Last और OrderBy से तेज है?

आम तौर पर

अगर मैं इस तरह के 'नवीनतम जोड़ा व्यक्ति' मैं की तरह कुछ लिखते हैं के रूप में एक रिकार्ड एक विशेष क्षेत्र, द्वारा आदेश दिया खोजने के लिए चाहता था:

MyCollection.OrderByDescending(x => x.AddedDate).FirstOrDefault(); 

हाल ही में मैं कुछ काम एक और देव से में उठाया टीम है जो लिखने के लिए पसंद करते हैं:

MyCollection.OrderBy(x => x.AddedDate).LastOrDefault(); 

तो मेरे सवाल यह है, उतरते का ऑर्डर दे रहे हैं और पहले के चयन, जल्दी या दूसरी दिशा आदेश देने और पिछले चुनाव से धीमा?

मेरे विचार ये हैं कि पहले ऑब्जेक्ट लौटने पर 'दूर तक' संग्रह पर पुनरावृत्ति करने की आवश्यकता नहीं होती है, लेकिन यह किसी और चीज़ की तुलना में अधिक झुकाव है!

+4

एक बेंचमार्क करें :) –

+0

असल में हाँ, बेंचमार्क मैं जवाब जानना भी चाहूंगा। – Maris

+0

आम तौर पर इसका परीक्षण करने का सबसे अच्छा तरीका प्रतिनिधि नमूना बनाना और इसे स्वयं आज़माएं। –

उत्तर

9

यदि आप LINQ-to-Objects का उपयोग कर रहे हैं, तो पहला मामूली तेज होगा। दो प्रकार प्रत्येक एक ही समय लेते हैं *, लेकिन आप सोच रहे हैं कि FirstOrDefaultLastOrDefault से तेज़ है। हालांकि, इस तरह के समय की तुलना में अंतर नगण्य होगा।

(नोट एक पूरी तरह कर बस ऊपर आइटम लेने के लिए कि कहीं अधिक LastFirst से अधिक का उपयोग करने से अक्षम है, बल्कि O(n log n) से आइटम आप O(n) में चाहते हैं, पाने के लिए MoreLINQ के MaxBy समारोह की तरह कुछ लागू करने पर विचार, समय।)

यदि आप LINQ-to-else (SQL, Entities) का उपयोग कर रहे हैं, तो शायद इससे कोई फर्क नहीं पड़ता।

* सामान्य रूप से; चूंकि आरबी बताता है कि यह मामला नहीं हो सकता है यदि डेटा पहले से ही कुछ हद तक आदेश दिया गया है।

+1

+1। जब आप प्रदर्शन के बारे में चिंतित हों तो अंतिम आइटम ढूंढने के लिए केवल एक संपूर्ण संग्रह को सॉर्ट करना गलत है। –

+0

यह भी दिलचस्प है: यदि आप 'LastOrDefault()' बनाम 'LastOrDefault (predicate) 'के कार्यान्वयन को देखते हैं, तो बाद में पूर्व में अनुकूलन (सूचियों के लिए) की कमी है। 'LastOrDefault() 'यह देखने के लिए कोई अनुमानित चेक नहीं है कि यह एक सूची है या नहीं, और उसके बाद गणना संख्या 1 पर तत्व लौटाती है, इसलिए यह बहुत तेज़ है। 'LastOrDefault (predicate)' में ऐसी कोई जांच नहीं है, इसलिए यह हमेशा 'गणना - i' से पुन: प्रयास करने और पहले मिलान करने वाले तत्व को लेने के बजाय' GetEnumerator' और 'MoveNext' विधियों का उपयोग करके शुरुआत से पूरी सूची में पुनरावृत्त करता है। कोई विचार नहीं कि उन्होंने इसे इस तरह क्यों लागू किया। – Triynko

+0

और यदि वे केवल वही ऑप्टिमाइज़ेशन जोड़ते हैं तो वे 'LastOrDefault() '(कोई predicate) में' LastOrDefault (predicate) 'में जोड़े गए हैं, तो यह परिमाण के तीन ऑर्डर के प्रदर्शन में वृद्धि देख सकता है।मैंने 'IList' ऑप्टिमाइज़ेशन के साथ 'LastOrDefault (predicate)' को फिर से कार्यान्वित किया, और इसे 'LastOrDefault (x => x == 99999)', और रन टाइम के लिए खोजते हुए आदेशित पूर्णांक के साथ 1 से 100,000 तक की सूची में चलाया 1000 कॉल के लिए 5548631 टिक थे, अनुकूलित संस्करण के लिए केवल 3214 बनाम। कितनी बड़ी निगरानी! – Triynko