2010-07-01 13 views
81

मैं एक मेश रेंडरिंग मैनेजर लिख रहा हूं और सोचा था कि एक ही शेडर का उपयोग करने वाले सभी मेषों को समूहित करना एक अच्छा विचार होगा और फिर उस शेडर पास में रहते हुए इन्हें प्रस्तुत करना अच्छा होगा।क्या 'foreach' लूप से LINQ कथन तेज है?

मैं वर्तमान में foreach लूप का उपयोग कर रहा हूं, लेकिन सोच रहा हूं कि LINQ का उपयोग करने से मुझे प्रदर्शन में वृद्धि हो सकती है?

+1

संभव डुप्लिकेट http://stackoverflow.com/questions/1044236/nested-foreach- बनाम-लैम्ब्डा-लिनक-क्वेरी-निष्पादन-से-ऑब्जेक्ट्स) –

+1

कृपया स्वीकार्य व्यक्ति के लिए @ मार्कक्रावेल के उत्तर को सेट करने पर विचार करें, उदाहरण हैं, उदाहरण के लिए linq to linq, जहां linq के लिए/foreach से तेज है। – paqogomez

उत्तर

144

LINQ तेज क्यों होना चाहिए? यह आंतरिक रूप से loops का भी उपयोग करता है।

ज्यादातर बार, LINQ थोड़ा धीमा हो जाएगा क्योंकि यह ओवरहेड पेश करता है। यदि आप प्रदर्शन के बारे में बहुत अधिक ध्यान रखते हैं तो LINQ का उपयोग न करें। LINQ का उपयोग करें क्योंकि आप छोटे बेहतर पठनीय और रखरखाव कोड चाहते हैं।

+6

तो आपका अनुभव यह है कि LINQ तेज है और कोड को पढ़ने और बनाए रखने के लिए कठिन बनाता है? कृपया समझाएँ। – codymanix

+56

मुझे लगता है कि आप इसे पिछड़ा था। वह कह रहा है कि LINQ धीमा है। यह सिर के कारण है। वह यह भी कह रहा है कि LINQ को पढ़ने और बनाए रखना आसान है। –

+1

क्षमा करें। इस बीच हमारे पास बहुत सी चीजें थीं जहां हमने लिनक की तुलना की थी और प्रदर्शन के लिए या भविष्यवाणी की थी, और अधिकांश समय लिनक तेज था। – Offler

14

मुझे लगता है कि LINQ foreach लूप पर उपयोग करना बेहतर है, क्योंकि यह आपको बहुत साफ और समझने योग्य कोड देता है। लेकिन LINQ foreach से धीमा है। अधिक पाने के लिए, आलेख LINQ vs FOREACH vs FOR Loop Performance पर जाएं।

8

यदि आप बहु कोर के लिए समानांतर LINQ का उपयोग करते हैं तो आपको एक प्रदर्शन बढ़ावा मिल सकता है। Parallel LINQ (PLINQ) (एमएसडीएन) देखें।

48

LINQ-to-Objects आमतौर पर कुछ मामूली ओवरहेड्स (एकाधिक इटरेटर, आदि) जोड़ने जा रहा है। यह अभी भी छोरों करना है, और का आह्वान, प्रतिनिधि है और आम तौर पर कब्जा कर लिया चर आदि सबसे कोड में यह लगभग undetectable हो जाएगा पर प्राप्त करने के लिए कुछ अतिरिक्त dereferencing करना होगा, और से अधिक द्वारा प्रदान कोड समझने के लिए आसान है।

LINQ करने वाली एसक्यूएल जैसे अन्य LINQ प्रदाताओं के साथ, तब से क्वेरी सर्वर पर फ़िल्टर कर सकते हैं यह होना चाहिए बहुत बेहतर एक फ्लैट foreach से है, लेकिन सबसे अधिक संभावना है आप एक कंबल "select * from foo"वैसे भी नहीं किया होता, इसलिए आवश्यक नहीं है एक उचित तुलना।

री PLINQ; समांतरता समय समाप्त हो सकती है, लेकिन कुल CPU समय आमतौर पर थ्रेड प्रबंधन आदि के ऊपरी हिस्से के कारण थोड़ा बढ़ाएगा

+0

एक और जवाब में आपने इन-मेमोरी संग्रहों पर LINQ का उपयोग करके * नहीं * को बताया - उदा। 'सूची '; इसके बजाय, मुझे इन संग्रहों पर 'foreach' ब्लॉक का उपयोग करना चाहिए। इन संदर्भों में 'foreach' का उपयोग करने की सिफारिश समझ में आता है। मेरी चिंता: क्या मुझे केवल LINQ प्रश्नों को 'foreach' * के साथ प्रतिस्थापित करना चाहिए * यदि * मुझे प्रदर्शन समस्या का पता लगाना चाहिए? आगे बढ़ते हुए, मैं पहले 'foreach' पर विचार करूंगा। – IAbstract

13

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

अधिक महत्वपूर्ण बात यह है कि, LINQ पढ़ने के लिए बहुत आसान है। यह पर्याप्त कारण होना चाहिए।

+3

मुझे यह पसंद है कि "माइक्रोसॉफ्ट इसे कार्यान्वित कर सकता है" क्या यह संभव है, मेरा मतलब है कि मैं ढांचे को अपग्रेड किए बिना संभव है? – Shrivallabh

+0

LINQ मूल कार्यान्वयन से वास्तव में कभी भी तेज नहीं होगा, क्योंकि दिन के अंत में, यह मूल कार्यान्वयन में अनुवाद करता है। कोई विशेष LINQ CPU निर्देश और LINQ रजिस्ट्रार नहीं हैं जिनका उपयोग तेजी से LINQ मशीन कोड का अनुवाद करने के लिए किया जा सकता है - और यदि वहां थे, तो वे गैर-LINQ कोड द्वारा भी उपयोग किए जाएंगे। – mg30rg

7

यह शायद ध्यान दिया जाना चाहिए कि for लूप foreach से तेज़ है। तो मूल पोस्ट के लिए, यदि आप एक रेंडरर जैसे महत्वपूर्ण घटक पर प्रदर्शन के बारे में चिंतित हैं, तो for लूप का उपयोग करें।

संदर्भ: In .NET, which loop runs faster, 'for' or 'foreach'?

2

मैं इस सवाल में रुचि थी, तो मैं बस अब एक परीक्षण किया था। इंटेल (आर) कोर (टीएम) i3-2328M CPU @ 2 पर .NET Framework 4.5.2 का उपयोग करना।20 गीगाहर्ट्ज, 2200 मेगाहर्ट्ज, 2 कोर (एस) 8 जीबी रैम के साथ माइक्रोसॉफ्ट विंडोज 7 अल्टीमेट चल रहा है।

ऐसा लगता है कि प्रत्येक लूप के लिए LINQ तेज हो सकता है।

Exists=True 
Time=174 
Exists=True 
Time=149 

यह अगर आप में से कुछ & साथ ही एक console ऐप्स और परीक्षण में इस कोड को कॉपी कर सकता है दिलचस्प होगा: यहाँ परिणाम मुझे मिल गया है। किसी ऑब्जेक्ट (कर्मचारी) के साथ परीक्षण करने से पहले मैंने पूर्ण परीक्षण के साथ एक ही परीक्षण की कोशिश की। LINQ भी तेज़ था।

public class Program 
{ 

    public class Employee 
    { 
     public int id; 
     public string name; 
     public string lastname; 
     public DateTime dateOfBirth; 

     public Employee(int id,string name,string lastname,DateTime dateOfBirth) 
     { 
      this.id = id; 
      this.name = name; 
      this.lastname = lastname; 
      this.dateOfBirth = dateOfBirth; 

     } 

    } 

    public static void Main() 
    { 

     StartObjTest(); 
    } 

    #region object test 

    public static void StartObjTest() 
    { 
     List<Employee> items = new List<Employee>(); 

     for (int i = 0; i < 10000000; i++) 
     { 
      items.Add(new Employee(i,"name" + i,"lastname" + i,DateTime.Today)); 
     } 

     Test3(items, items.Count-100); 
     Test4(items, items.Count - 100); 

     Console.Read(); 
    } 


    public static void Test3(List<Employee> items, int idToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = false; 
     foreach (var item in items) 
     { 
      if (item.id == idToCheck) 
      { 
       exists = true; 
       break; 
      } 
     } 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    public static void Test4(List<Employee> items, int idToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = items.Exists(e => e.id == idToCheck); 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    #endregion 


    #region int test 
    public static void StartIntTest() 
    { 
     List<int> items = new List<int>(); 

     for (int i = 0; i < 10000000; i++) 
     { 
      items.Add(i); 
     } 

     Test1(items, -100); 
     Test2(items, -100); 

     Console.Read(); 
    } 

    public static void Test1(List<int> items,int itemToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = false; 
     foreach (var item in items) 
     { 
      if (item == itemToCheck) 
      { 
       exists = true; 
       break; 
      } 
     } 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    public static void Test2(List<int> items, int itemToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = items.Contains(itemToCheck); 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    #endregion 

} 
0

यह वास्तव में एक जटिल सवाल है। लिंक कुछ चीजों को करने में बहुत आसान बनाता है, कि यदि आप उन्हें स्वयं लागू करते हैं, तो आप ठोकर खा सकते हैं (उदा। Linq .xcept())। यह विशेष रूप से PLinq पर लागू होता है, और विशेष रूप से पीएलआईएनक द्वारा लागू समानांतर समेकन के लिए।

आम तौर पर, समान कोड के लिए, प्रतिनिधि आमंत्रण के ओवरहेड की वजह से, लिनक धीमा हो जाएगा।

अगर अगर, हालांकि, आप डेटा की विस्तृत शृंखला को कार्रवाई कर रहे हैं, और तत्वों के अपेक्षाकृत सरल गणना को लागू करने के लिए, आप एक विशाल प्रदर्शन वृद्धि मिल जाएगा:

  1. आप डाटा स्टोर करने की एक सरणी का उपयोग करें।
  2. आप प्रत्येक तत्व तक पहुंचने के लिए लूप का उपयोग करते हैं (जैसा कि foreach या linq के विपरीत)।

    • नोट: जब बेंचमार्किंग, कृपया सभी को याद रखें - यदि आप लगातार दो परीक्षणों के लिए एक ही सरणी/सूची का उपयोग करते हैं, तो CPU कैश दूसरे को तेज़ी से बना देगा। *
[ "नेस्टेड foreach" बनाम "लैम्ब्डा/LINQ क्वेरी" प्रदर्शन (LINQ करने वाली वस्तुओं)] (की
संबंधित मुद्दे