2009-09-04 9 views
26

मुझे वास्तव में Last() पसंद है और List<T> s के लिए हर समय इसका उपयोग करेगा। लेकिन चूंकि इसे IEnumerable<T> के लिए परिभाषित किया गया है, मुझे लगता है कि यह पहले गणना को दर्शाता है - यह ओ (एन) के विपरीत होना चाहिए (0) List<T> के अंतिम तत्व को सीधे अनुक्रमणित करने के लिए।सूची <T> सूची के लिए अंतिम() एक्सटेंशन विधि का प्रदर्शन क्या है?

क्या मानक (लिंक) एक्सटेंशन विधियां इस बारे में जागरूक हैं?

सी ++ में एसटीएल इसके बारे में जागरूक और व्हाट्नॉट के लिए पूरे "विरासत पेड़" के आधार पर इसके बारे में पता है।

+0

इटरेटर के लिए विरासत का पेड़ क्या है? सी ++ में पहले स्थान पर एक्सटेंशन विधियां नहीं हैं, इसलिए 'वेक्टर' पर 'एंड() 'को' सूची 'से अलग तरीके से कार्यान्वित किया गया है, और जो भी किसी के लिए इटरेटर के साथ काम करना चाहता है वह' टेम्पलेट 'होना चाहिए 'Iterator' प्रकार पैरामीटर पर। –

उत्तर

30

मैं सिर्फ परावर्तक इस्तेमाल किया अंतिम के लिए कोड की जांच के लिए और यह अगर यह होता है एक IList<T> पहले देखने के लिए जाँच करता है और उचित हे करता है (1) कॉल:


संपादित करें:

मेरे वकील की सलाह पर मैंने परावर्तक से कोड स्निपेट हटा दिया है। यदि आप अपने लिए कोड देखना चाहते हैं तो मेरा सुझाव है कि आप या तो परावर्तक प्राप्त करें और इसे स्वयं करें (जो सभी को पहले से ही होना चाहिए) या अधिक आसानी से इस पोस्ट के संशोधन इतिहास में देखें (क्योंकि इसके बारे में मैं कुछ भी नहीं कर सकता)

(या वास्तव में मार्क के जवाब को देखो, जो स्पष्ट रूप से एक ही दरार कानूनी उसे की रक्षा टीम नहीं है)


तो तुम एक कलाकारों के मामूली भूमि के ऊपर है, लेकिन नहीं की गणना की भारी भूमि के ऊपर है।

+0

एक मुद्दा जो हाइलाइट किया गया था (और अब टिप्पणियां हटा दी गई हैं जो मुझे एक बेवकूफ बेवकूफ की तरह दिख रही हैं) यह है कि कोई भी ढांचे के कार्यान्वयन पर काम कर रहा है - जैसे मोनो - कभी भी कोई कोड नहीं देख सकता माइक्रोसॉफ्ट ने इतनी कम से कम लिखा है कि इसे स्पष्ट रूप से पोस्ट करना मुश्किल है। मुझे वास्तव में यह देखने के लिए बहुत भाग्य नहीं है कि यह वास्तव में * अवैध * है और मुझे यह उद्धरण देखने में दिलचस्पी होगी कि यह है। यहां नियम देखें http://www.mono-project.com/ –

+8

योगदान देना संभवतः मेरी कुर्सी के पहियों की तस्वीर पोस्ट करना भी अवैध है, क्योंकि किसी ने इसे आमंत्रित किया है। कभी-कभी मुझे लगता है कि लोग कॉपीराइट मुद्दों के बारे में पागल हो जाते हैं। –

+0

मैंने यहां मेटा पर एक प्रश्न पोस्ट किया है (http://meta.stackexchange.com/questions/20153/posting-code-from-reflector) जो मुझे बहुत आश्वस्त करता है कि * अवैध है। जैसा कि मैंने उल्लेख किया है, हालांकि मैंने इसे केवल हटा दिया है क्योंकि कुछ टिप्पणियां (जिन्हें अब भी हटा दिया गया है) ने सुझाव दिया है कि मैंने किया था। मैंने पहले परावर्तक से कोड पोस्ट किया है और मुझे यकीन है कि मैं फिर से करूंगा। मैं माइक्रोसॉफ्ट कॉपीराइट एसडब्ल्यूएटी टीम के लिए अपने कंधे पर नहीं देख रहा हूं क्योंकि मैं तर्क दूंगा कि .NET लाभों में समझ और विश्वास में सुधार करने के लिए कुछ भी माइक्रोसॉफ्ट वैसे भी है। –

7

इसमें IList<T> लागू करने वाली किसी भी चीज़ के लिए अनुकूलन शामिल है, इस स्थिति में यह केवल लंबाई -1 पर आइटम को देखता है।

ध्यान रखें कि सामान के विशाल बहुमत आप में भेज देंगे IList<T>

List<int> 
int[] 

और इतने पर लागू करेगा ... सभी को लागू IList<T>

जो लोग कोड में नहीं देख सकते हैं के लिए

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 

namespace ConsoleApplication4 { 
    class Program { 

     static void Profile(string description, int iterations, Action func) { 

      // clean up 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
      GC.Collect(); 

      // warm up 
      func(); 

      var watch = Stopwatch.StartNew(); 
      for (int i = 0; i < iterations; i++) { 
       func(); 
      } 
      watch.Stop(); 
      Console.Write(description); 
      Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds); 
     } 

     static void Main(string[] args) { 
      int[] nums = Enumerable.Range(1, 1000000).ToArray(); 

      int a; 

      Profile("Raw performance", 100000,() => { a = nums[nums.Length - 1]; }); 
      Profile("With Last", 100000,() => { a = nums.Last(); }); 

      Console.ReadKey(); 
     } 


    } 
} 

आउटपुट::

0,123,516 पुष्टि करते हैं, आप इसे अवलोकन का उपयोग कर पुष्टि कर सकते हैं
 
Raw performance Time Elapsed 1 ms 
With Last Time Elapsed 31 ms 

तो यह केवल 30 गुना धीमा है और आपके पास जो भी लंबाई सूची है, उस प्रदर्शन प्रोफ़ाइल को बनाए रखता है, जो चीजों की बड़ी योजना में कुछ भी नहीं है।

+0

बस एक छोटा सा नाइटपिक: 'हैशसेट '' IList 'लागू नहीं करता है। – LukeH

+0

@ ल्यूक, धन्यवाद, –

2

List<T> के लिए यह ओ (1) है, लेकिन अन्य गणित के लिए यह ओ (एन) हो सकता है।

21

तुम बस चिंता :)

Enumerable.Last IList<T> को IEnumerable<T> उदाहरण खिन्न करने का प्रयास के बिना List<T> साथ अंतिम उपयोग कर सकते हैं। यदि यह संभव है, तो यह सूचकांक और गणना संपत्ति का उपयोग करता है।

यहाँ कार्यान्वयन का हिस्सा है के रूप में Reflector यह देखता है:

IList<TSource> list = source as IList<TSource>; 
if (list != null) 
{ 
    int count = list.Count; 
    if (count > 0) 
    { 
     return list[count - 1]; 
    } 
} 
0

लघु जवाब:

हे (1)।

स्पष्टीकरण:

ऐसा नहीं है कि अंतिम() के लिए सूची का उपयोग करता गणना() विस्तार विधि स्पष्ट है।

गणना() क्रम में संग्रह की चेकों के प्रकार और गणना संपत्ति का उपयोग करता है, तो यह उपलब्ध है। सूची के लिए

गणना संपत्ति हे (1) जटिलता इसलिए अंतिम() विस्तार विधि है।

+0

'अंतिम' * * गणना 'एक्सटेंशन विधि का उपयोग नहीं करता है, लेकिन आप सही हैं कि कुछ परिस्थितियों में दोनों विधियां ओ (1) हो सकती हैं:' आखिरी 'जांच करता है कि संग्रह' IList 'लागू करता है और यदि ऐसा है तो गणना के बजाय सूचकांक द्वारा अंतिम तत्व प्राप्त करता है; 'गणना' विधि जांचती है कि संग्रह 'ICollection ' लागू करता है और यदि ऐसा है तो गणना करने के बजाए 'गणना' संपत्ति प्राप्त होती है। – LukeH

+0

ल्यूक धन्यवाद, मैं 100% सही नहीं था। अंतिम आईएलिस्ट के लिए संपत्ति गणना का उपयोग करता है और ओ (1) की जटिलता है। मैंने अभी अंतिम (इस संग्रह, predicate) के लिए कोड की जांच की है और यह ओ (एन) है। वह आलसी है। –

+0

@ कॉन्स्टेंटिन: यदि आप 'अंतिम' विधि को भविष्यवाणी करते हैं तो उसे संग्रह के ओ (एन) गणना को निर्धारित करना होगा कि कौन से आइटम भविष्यवाणी से मेल खाते हैं। – LukeH

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