Czy instrukcja LINQ jest szybsza niż pętla 'foreach'?

Piszę Menedżera renderowania siatki i pomyślałem, że dobrym pomysłem byłoby zgrupowanie wszystkich siatek, które używają tego samego shadera, a następnie renderowanie ich, gdy jestem w tym przejściu shadera.

Obecnie używam pętli foreach, ale zastanawiałem się, czy wykorzystanie LINQ może zwiększyć wydajność?

Author: user247702, 2010-07-01

7 answers

Dlaczego LINQ ma być szybszy? Używa również pętli wewnętrznie.

Przez większość czasu LINQ będzie nieco wolniejszy, ponieważ wprowadza overhead. Nie używaj LINQ, jeśli zależy ci na wydajności. Używaj LINQ, ponieważ chcesz krótszego, lepiej czytelnego i łatwego do utrzymania kodu.

 241
Author: codymanix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-01 08:21:12

LINQ-to-Objects ogólnie będzie dodawał jakieś marginalne koszty ogólne (wiele iteratorów, itp.). Nadal musi wykonywać pętle, i mA wywołania delegatów, i będzie musiał wykonać dodatkowe dereferencje, aby uzyskać przechwycone zmienne itp. W większości kodĂłw bÄ ™ dzie to praktycznie niewykrywalne, a wiÄ ™ cej niĹź zapewnione przez prostszy do zrozumienia kod.

Z innymi dostawcami LINQ jak LINQ-to-SQL, to skoro zapytanie może filtrować na serwerze to powinno być dużo lepsze niż mieszkanie foreach, ale najprawdopodobniej nie zrobiłbyś koca "select * from foo" w każdym razie , więc to nie jest koniecznie uczciwe porównanie.

Re PLINQ; równoległość może skrócić upłynął Czas, ale całkowity czas procesora Zwykle zwiększy się nieco ze względu na ogólne koszty zarządzania wątkami itp.

 65
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-01 08:23:53

LINQ jest teraz wolniejszy, ale w pewnym momencie może być szybszy. Dobrą rzeczą w LINQ jest to, że nie musisz dbać o to, jak to działa. Jeśli opracowana zostanie nowa metoda, która jest niewiarygodnie szybka, ludzie w firmie Microsoft mogą ją zaimplementować, nawet nie mówiąc ci o tym, a Twój kod będzie o wiele szybszy.

Co ważniejsze, LINQ jest o wiele łatwiejszy do odczytania. To powinien być wystarczający powód.

 16
Author: Jouke van der Maas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 20:32:39

Należy prawdopodobnie zauważyć, że pętla for jest szybsza niż foreach. Tak więc w oryginalnym poście, jeśli martwisz się o wydajność krytycznego komponentu, takiego jak renderer, użyj pętli for.

Odniesienie: W. NET, która pętla działa szybciej, " for " czy "foreach"?

 14
Author: peewee_RotA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:29

Możesz zwiększyć wydajność, jeśli używasz równoległego LINQ dla wielu rdzeni. Zobacz też równoległe LINQ (PLINQ) (MSDN).

 9
Author: mcintyre321,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 20:29:24

Byłem zainteresowany tym pytaniem, więc zrobiłem test właśnie teraz. Korzystanie z. NET Framework 4.5.2 na procesorze Intel (R) Core(TM) I3-2328M @ 2.20 GHz, 2200 Mhz, 2 rdzeń(Y) Z 8GB ram z systemem Microsoft Windows 7 Ultimate.

Wygląda na to, że LINQ może być szybszy niż dla każdej pętli. Oto wyniki, które otrzymałem:

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

Byłoby interesujące, gdyby niektórzy z was mogli skopiować i wkleić ten kod do aplikacji konsolowej i przetestować go. Przed testowaniem z obiektem (pracownikiem) próbowałem tego samego test z liczbami całkowitymi. Tam też LINQ był szybszy.

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

}
 5
Author: Theo Kand.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 08:09:28

To dość złożone pytanie. Linq sprawia, że pewne rzeczy są bardzo łatwe do zrobienia, że jeśli zaimplementujesz je samodzielnie, możesz się potknąć (np.Z wyjątkiem()). Dotyczy to zwłaszcza PLinq, a zwłaszcza równoległej agregacji zaimplementowanej przez PLinq.

Ogólnie rzecz biorąc, dla identycznego kodu, linq będzie wolniejszy, ze względu na narzut wywołania delegata.

Jeśli jednak przetwarzasz dużą tablicę danych i stosujesz stosunkowo proste obliczenia do elementów, otrzymasz ogromny wzrost wydajności, Jeśli:

  1. używasz tablicy do przechowywania danych.
  2. Używasz pętli for, aby uzyskać dostęp do każdego elementu(w przeciwieństwie do foreach lub linq).

    • UWAGA: podczas benchmarkingu, proszę pamiętać-jeśli używasz tej samej tablicy/listy przez dwa kolejne testy, pamięć podręczna procesora sprawi, że drugi będzie szybszy. *
 3
Author: Adam Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 13:27:33