LINQ स्टेटमेंट 'foreach' लूप से तेज है?


124

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

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



1
कृपया स्वीकार किए जाने वाले @ MarcGravell के उत्तर को सेट करने पर विचार करें, ऐसी स्थितियाँ हैं, उदाहरण के लिए linq to sql, जहाँ linq for / foreach की तुलना में तेज़ है।
paqogomez

जवाबों:


222

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

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


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

87
मुझे लगता है कि आप इसे पिछड़ा हुआ था। वह कह रहा है LINQ SLOWER है। यह ओवर हेड के कारण होता है। वह यह भी कह रहा है कि LINQ पढ़ना और बनाए रखना आसान है।
जोसेफ मैकइंटायर

5
माफ़ करना। इस दौरान हमारे पास बहुत सी चीजें थीं, जहां हमने linq और for या foreach के प्रदर्शन की तुलना की, और ज्यादातर समय linq तेज था।
ऑफकर्ल

34
मेरी राय में ईमानदार होने के लिए, एक फॉरेक्स लूप इसकी LINQ विधि से अधिक पठनीय है। मैं LINQ का उपयोग करता हूं क्योंकि यह अच्छा है :)
LuckyLikey

4
हां, लेकिन कुछ मामलों में LINQ वास्तव में पठनीयता में सुधार कर सकता है, इसलिए मेरी नासमझ टिप्पणी को भूल
जाइए

59

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

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

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


एक अन्य उत्तर में आपने इन-मेमोरी मेमोरी पर LINQ का उपयोग नहीं करने के लिए कहा - जैसे List<Foo>; इसके बजाय, मुझे foreachइन संग्रहों पर एक ब्लॉक का उपयोग करना चाहिए । foreachइन संदर्भों में उपयोग करने की सिफारिश का कोई मतलब नहीं है। मेरी चिंता: foreach यदि मुझे प्रदर्शन समस्या का पता चलता है, तो मुझे केवल LINQ प्रश्नों को प्रतिस्थापित करना चाहिए ? आगे जाकर, मैं foreachपहले विचार करूंगा ।
आइब्रीस्ट

19

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


15

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

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


3
मुझे वह लाइन पसंद है "Microsoft इसे लागू कर सकता है" क्या यह संभव है, मेरा मतलब है कि क्या मैं फ्रेमवर्क को उन्नत किए बिना संभव है?
श्रीवल्लभ

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

कोई सच नहीं, कुछ बिंदु पर कुछ लिंक ऑपरेशन बहु-थ्रेडेड हो सकते हैं या कुछ बिंदु पर GPU का उपयोग भी कर सकते हैं।
जॉन स्टॉक

11

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

संदर्भ: .NET में, कौन सा लूप तेज चलता है, 'फॉर' या 'फॉरच'?


9

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


5

मुझे इस सवाल में दिलचस्पी थी, इसलिए मैंने अभी एक परीक्षण किया। Intel (R) Core (TM) i3-2328M CPU @ 2.20GHz, 2200 Mhz, 2 Core (s) पर 8GB RAM वाला माइक्रोसॉफ्ट विंडोज 7 अल्टीमेट चल रहा है।

ऐसा लगता है कि LINQ प्रत्येक लूप की तुलना में तेज़ हो सकता है। यहां मुझे मिले परिणाम हैं:

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

यह दिलचस्प होगा यदि आप में से कुछ इस कोड को कंसोल ऐप और टेस्ट में कॉपी और पेस्ट कर सकते हैं। किसी ऑब्जेक्ट (कर्मचारी) के साथ परीक्षण करने से पहले मैंने पूर्णांक के साथ एक ही परीक्षण की कोशिश की। 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

}

यह वही है जो मैंने प्राप्त किया है: अस्तित्व = सही समय = 274
अस्तित्व

2
क्या आपने पहले
लाइनक

3
दिलचस्प। मुझे मिल गया है Exists=True Time=184 Exists=True Time=135यह एक अपाचे गेमिंग लैपटॉप पर है (विन 10, सी # 7.3)। संकलित और डिबग मोड में चला गया। अगर मुझे मिलने वाले परीक्षणों को उल्टा कर दिया जाए Exists=True Time=158 Exists=True Time=194। लगता है Linq अधिक अनुकूलित है मुझे लगता है।
जेम्स विल्किंस

1
ऑब्जेक्ट टेस्ट के बारे में इस पोस्ट में गलतफहमी है। हालांकि यह निश्चित रूप से दिलचस्प है कि List.Exists और .Contains फ़ॉरच से बेहतर प्रदर्शन करते हैं। यह ध्यान रखना महत्वपूर्ण है कि .Exists संस्थाओं की विधि के लिए एक linq नहीं है और केवल सूचियों पर काम करेगा, इसके linq समकक्ष विधि, .Any (), निश्चित रूप से foreach की तुलना में धीमी गति से कार्य करता है।
अब्दुलग

3

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

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

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

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

    • नोट: बेंचमार्किंग करते समय, कृपया सभी को याद रखें - यदि आप लगातार दो परीक्षणों के लिए एक ही सरणी / सूची का उपयोग करते हैं, तो सीपीयू कैश दूसरा तेज़ी से बना देगा। *
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.