代码之家  ›  专栏  ›  技术社区  ›  Neil Knight

LINQ语句比“foreach”循环快吗?

  •  98
  • Neil Knight  · 技术社区  · 14 年前

    我正在编写一个网格渲染管理器,并认为这将是一个好主意,以集团所有的网格使用相同的着色器,然后渲染这些,而我在该着色器通过。

    foreach 循环,但不知道使用LINQ是否可以提高性能?

    8 回复  |  直到 8 年前
        1
  •  246
  •   codymanix    14 年前

    为什么LINQ要更快?它也在内部使用循环。

        2
  •  66
  •   Marc Gravell    14 年前

    LINQ到对象 将添加一些边际开销(多个迭代器等)。它还得做循环, 有委托调用, 超过 由更简单易懂的代码提供。

    对于其他LINQ提供程序,比如linqtosql,那么由于查询可以在服务器上进行过滤,所以它应该非常有用 更好的 而不是公寓 foreach "select * from foo" 无论如何 ,所以这不是 一个公平的比较。

    重新定位;并行性可能会降低 逝去 但是由于线程管理等方面的开销,总CPU时间通常会增加一点。

        3
  •  17
  •   Peter Mortensen icecrime    9 年前

    LINQ现在比较慢,但在某个时候可能会更快。LINQ的好处是你不必关心它是如何工作的。如果一个新的方法被认为是难以置信的快,在微软的人可以实现它,甚至不告诉你,你的代码会快得多。

    但更重要的是,LINQ更容易阅读。这应该是足够的理由了。

        4
  •  15
  •   Community Lee    7 年前

    可能应该注意的是 for 循环比循环快 foreach . 因此,对于最初的文章,如果您担心关键组件(如渲染器)的性能,请使用 对于

    参考文献: In .NET, which loop runs faster, 'for' or 'foreach'?

        5
  •  9
  •   Peter Mortensen icecrime    9 年前

    如果对多核使用并行LINQ,可能会提高性能。看到了吗 Parallel LINQ (PLINQ) (MSDN)。

        6
  •  6
  •   AustinWBryan ravenspoint    6 年前

    我对这个问题很感兴趣,所以刚才做了一个测试。在Intel(R)Core(TM)i3-2328M CPU上使用.NET Framework 4.5.2,处理器为2.20GHz,2200 Mhz,2核,8GB ram,运行Microsoft Windows 7 Ultimate。

    以下是我得到的结果:

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

    如果你们中的一些人能够复制;将此代码粘贴到控制台应用程序中并进行测试。 在对对象(雇员)进行测试之前,我对整数进行了相同的测试。林克在那里也更快。

    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
    
    }
    
        7
  •  3
  •   Adam Brown    7 年前

    这实际上是一个相当复杂的问题。Linq使某些事情非常容易做,如果您自己实现它们,您可能会绊倒(例如Linq.Except())。这尤其适用于PLinq,尤其是PLinq实现的并行聚合。

    一般来说,对于相同的代码,由于委托调用的开销,linq会比较慢。

    1. 使用数组存储数据。
    2. 使用for循环访问每个元素(与foreach或linq相反)。