2012-03-30 19 views
25

मैं सिर्फ स्टाइल और प्रदर्शन के बारे में सोच रहा हूं। इससे पहले मैं, की तरह कुछ लिखने के लिएनया [] या नई सूची <T>?

var strings = new List<string> { "a", "b", "c" }; 
var ints = new List<int> { 1, 2, 3}; 

इस्तेमाल किया लेकिन अब मैं इस शैली अधिक पसंद करने के लिए,

var strings = new [] { "a", "b", "c" }.ToList(); 
var ints = new [] { 1, 2, 3}.ToList(); 

मैं दूसरी शैली पसंद करते हैं, लेकिन अब पर विचार करते हैं - यह वास्तव में है जैसे कि यह लिखने के लायक है वह या शायद यह कुशल नहीं है और अधिक परिचालन की आवश्यकता है?

+0

कारण है कि आप दूसरी पसंद करते हैं मैं भी 2 शैली – Magrangs

+8

पसंद करते हैं अंदाज? मुझे लगता है कि यह कम पठनीय है, खासकर जब 'var' का उपयोग करते समय। –

+0

क्या आपने इस पर कुछ प्रदर्शन परीक्षण करने की कोशिश की है? बस इसे समय दें और उस परीक्षण से अवतार मूल्यों को देखें। – Frederiek

उत्तर

42

मैं डारिन से असहमत हूं: वे प्रदर्शन के संदर्भ में समकक्ष हैं। बाद वाले संस्करण को एक नई सरणी बनाना है, और ToList फिर इसे नई सूची में कॉपी करेगा। संग्रह प्रारंभकर्ता संस्करण के बराबर है:

var tmp = new List<int>(); 
tmp.Add(1); 
tmp.Add(2); 
tmp.Add(3); 
var ints = tmp; 

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

प्रदर्शन अंतर नगण्य होने की संभावना है, लेकिन यह गैर शून्य है (और किसी भी दिशा में स्पष्ट रूप से बेहतर नहीं - सरणी संस्करण में कम कॉल, लेकिन अधिक आवंटन देखते हैं)।

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

व्यक्तिगत रूप से मैं पहला फॉर्म पसंद करता हूं - मुझे लगता है कि यह स्पष्ट करता है कि आप शुरुआत से ही एक सूची का उपयोग कर रहे हैं।

public static class Lists 
{ 
    public static List<T> Of<T>(T item0) 
    { 
     return new List<T> { item0 }; 
    } 

    public static List<T> Of<T>(T item0, T item1) 
    { 
     return new List<T> { item0, item1 }; 
    } 

    public static List<T> Of<T>(T item0, T item1, T item2) 
    { 
     return new List<T> { item0, item1, item2 }; 
    } 

    ... as many times as you really care about, then ... 

    public static List<T> Of<T>(params T[] items) 
    { 
     return items.ToList(); 
    } 
} 

तो फिर तुम लिख सकते हैं:: एक अन्य विकल्प अपने स्वयं के स्थिर कक्षा में लिखने के लिए होगा

var ints = Lists.Of(1); 
var ints = Lists.Of(1, 2, 3); 
var ints = Lists.Of(1, 2, 3, 5, 6, 7, 8); // Use the params version 

यह अभी भी यह स्पष्ट है कि आप सूचियों का उपयोग कर रहे है, लेकिन प्रकार निष्कर्ष का लाभ लेता है।

आप अच्छी तरह से यह overkill विचार कर सकते हैं, हालांकि :)

+0

1+। मैं यही कहना चाहता था! बहुत सी सरणी प्रतिलिपि हो रही है और यह ** मुक्त नहीं है **। – Aliostad

+0

तो, आपका मतलब है कि पहले संस्करण को 'प्रदर्शन' करना चाहिए, है ना? –

+0

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

6

मुझे लगता है कि पहले मामले तत्वों को स्वचालित रूप से सूची में जोड़ा जाता है जबकि दूसरे में पहली बार एक सरणी बनाई जाती है, फिर इसे पुनरावृत्त किया जाता है और प्रत्येक तत्व सूची में जोड़ा जाता है।

शायद दूसरा एक एक वास्तविक सरणी सृजन यह देख लायक है से बचने के लिए अनुकूलित किया जाएगा कि इस आपरेशन एक पाश अंदर किया जाता है, तो आप शायद दो बार वस्तु आवंटन राशि (जब तक यह straightly अनुरूप होता है) करने के लिए कोई वास्तविक आवश्यकता के साथ वो करें।

आप बाईटकोड की जाँच करनी चाहिए इसके बारे में सुनिश्चित करने के लिए।

मैं सी # internals के शौकीन नहीं हूँ हालांकि बहुत देखभाल के साथ इस ले!

+0

+1 ऑब्जेक्ट आवंटन से दो बार ' –

13

प्रदर्शन परिप्रेक्ष्य से दोनों के बीच अंतर को अलग करना, पूर्व व्यक्त करता है कि आप बेहतर तरीके से हासिल करने की कोशिश कर रहे हैं। इन सामग्री के साथ तार की एक सरणी की घोषणा

इन सामग्री

और

साथ स्ट्रिंग की एक सूची की घोषणा और फिर इसे परिवर्तित:

अंग्रेजी में कोड व्यक्त विचार करें स्ट्रिंग की एक सूची में

मेरे लिए, पहला अधिक प्राकृतिक लगता है। हालांकि मैं स्वीकार करता हूं कि दूसरा आपके लिए बेहतर हो सकता है।

+0

यह वही है जो मैंने आपके जवाब को पढ़ने से पहले एक सेकंड पहले सोचा था :) –

7

उदाहरण 1 (वर ints = नई सूची {1, 2, 3};): एक 31.5% भूमि के ऊपर (Eumerable.ToList) और List.Add प्रदान करता है () 8.7% ओवरहेड का कारण बनता है।

उदाहरण के रूप में 2: List.ctor पर 11.8% ओवरहेड और एनसुर क्षमता के लिए 5% का कारण बनता है।

आपको लगता है कि वर ints = नई सूची देख सकते हैं (लाल गेट चींटियों प्रदर्शन प्रोफाइलर से परिणाम) {1, 2, 3}; अधिक संचालन disassembly

var intsx = new[] {1, 2, 3}.ToList(); 
0000003f mov   edx,3 
00000044 mov   ecx,60854186h 
00000049 call  FFF5FD70 
0000004e mov   dword ptr [ebp-4Ch],eax 
00000051 lea   ecx,[ebp-50h] 
00000054 mov   edx,872618h 
00000059 call  61490806 
0000005e lea   eax,[ebp-50h] 
00000061 push  dword ptr [eax] 
00000063 mov   ecx,dword ptr [ebp-4Ch] 
00000066 call  614908E3 
0000006b mov   ecx,dword ptr [ebp-4Ch] 
0000006e call  dword ptr ds:[008726D8h] 
00000074 mov   dword ptr [ebp-54h],eax 
00000077 mov   eax,dword ptr [ebp-54h] 
0000007a mov   dword ptr [ebp-40h],eax 

var ints = new List<int> { 1, 2, 3 }; 
0000007d mov   ecx,60B59894h 
00000082 call  FFF5FBE0 
00000087 mov   dword ptr [ebp-58h],eax 
0000008a mov   ecx,dword ptr [ebp-58h] 
0000008d call  60805DB0 
00000092 mov   eax,dword ptr [ebp-58h] 
00000095 mov   dword ptr [ebp-48h],eax 
00000098 mov   ecx,dword ptr [ebp-48h] 
0000009b mov   edx,1 
000000a0 cmp   dword ptr [ecx],ecx 
000000a2 call  608070C0 
000000a7 nop 
000000a8 mov   ecx,dword ptr [ebp-48h] 
000000ab mov   edx,2 
000000b0 cmp   dword ptr [ecx],ecx 
000000b2 call  608070C0 
000000b7 nop 
000000b8 mov   ecx,dword ptr [ebp-48h] 
000000bb mov   edx,3 
000000c0 cmp   dword ptr [ecx],ecx 
000000c2 call  608070C0 
000000c7 nop 
000000c8 mov   eax,dword ptr [ebp-48h] 
000000cb mov   dword ptr [ebp-44h],eax 
     } 
+3

इन 'कॉल' क्या करते हैं? उनकी लागत क्या है? –

+0

मेरे पास सटीक लागत देने के लिए कोई प्रोफाइलिंग टूल इंस्टॉल नहीं है, यह डिस्सेप्टर्स से कच्चा आउटपुट है जो आपको दिखाता है कि प्रश्न में दोनों उदाहरणों के लिए कितने ऑपरेशन किए जाते हैं। स्थापित और संपादित करेंगे। –

+0

@ एल.बी ने आपके द्वारा अपडेट की गई लागत प्रदान करने के लिए मेरा उत्तर अपडेट किया। –

1

मैं पहले संस्करण की तरह के माध्यम से पालन किया है। लेकिन के बारे में कार्यक्षमता मुझे लगता है कि सबसे अच्छा सरणी का उपयोग करें और परिभाषित विशेष रूप से तत्वों की संख्या है, तो निश्चित रूप से यह संभव हो सकता है होने जा रहा है के लिए है:

var x = new int[3] { 1, 3, 3 }.ToList(); 
+0

मुझे नहीं लगता कि स्पष्ट रूप से सरणी आकार निर्दिष्ट करने से कुछ भी जोड़ा जाता है। संकलक स्थिर विश्लेषण के माध्यम से इसे निर्धारित कर सकते हैं; और 'सूची ' किसी भी मामले में कन्स्ट्रक्टर पसंद करने के आकार पर बनाया जाएगा। –

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