LINQ 문이 ‘foreach’루프보다 빠릅니까? 메시를 그룹화 한 다음 셰이더 패스에있는

저는 Mesh Rendering 관리자를 작성 중이며 동일한 셰이더를 사용하는 모든 메시를 그룹화 한 다음 셰이더 패스에있는 동안이를 렌더링하는 것이 좋습니다.

현재 foreach루프를 사용하고 있지만 LINQ를 사용하면 성능이 향상 될 수 있는지 궁금하십니까?



답변

LINQ가 더 빨라야하는 이유는 무엇입니까? 또한 내부적으로 루프를 사용합니다.

대부분의 경우 LINQ는 오버 헤드를 유발하기 때문에 약간 느립니다. 성능에 관심이 많으면 LINQ를 사용하지 마십시오. 더 짧고 읽기 쉽고 유지 관리가 쉬운 코드를 원하기 때문에 LINQ를 사용하십시오.


답변

LINQ-to-Objects는 일반적으로 약간의 한계 오버 헤드 (다중 반복기 등)를 추가합니다. 아직 루프를 수행하는, 그리고 위임 원용을 가지고, 그리고 일반적으로는 거의 발견 할 수없는 것입니다 대부분의 코드에서 촬영 된 변수 등을 얻을 수있는 몇 가지 여분의 역 참조를해야 할 것이며, 더 이상의 코드를 이해하기 위해 간단한에 의해 제공.

LINQ-to-SQL과 같은 다른 LINQ 공급자를 사용하면 쿼리가 서버에서 필터링 할 수 있으므로 flat보다 훨씬 낫지어쨌든foreach 블랭킷을 수행하지 않았을 가능성이 높 으므로 반드시 공정 하지는 않습니다 . 비교."select * from foo"

Re PLINQ; 병렬 처리는 경과 시간을 줄일 수 있지만 일반적으로 총 CPU 시간은 스레드 관리 오버 헤드 등으로 인해 약간 증가합니다.


답변

LINQ는 foreach훨씬 깔끔하고 이해하기 쉬운 코드를 제공하기 때문에 루프를 통해 사용하는 것이 더 낫다고 생각 합니다. 그러나 LINQ는 foreach. 자세한 내용은 LINQ vs FOREACH vs FOR Loop Performance 기사를 참조하십시오 .


답변

LINQ는 현재 더 느리지 만 어느 시점에서는 더 빨라질 수 있습니다. LINQ의 좋은 점은 작동 방식에 신경 쓸 필요가 없다는 것입니다. 엄청나게 빠른 새로운 방법이 생각되면 Microsoft 직원은 사용자에게 말하지 않고도 구현할 수 있으며 코드가 훨씬 빨라질 것입니다.

하지만 더 중요한 것은 LINQ가 훨씬 읽기 쉽다는 것입니다. 충분한 이유가되어야합니다.


답변

아마도 주목해야한다 for루프가 빠르게보다 foreach. 따라서 원본 게시물의 경우 렌더러와 같은 중요한 구성 요소의 성능이 걱정된다면 for루프를 사용하십시오 .

참조 :
.NET에서 ‘for’또는 ‘foreach’중 어떤 루프가 더 빠르게 실행됩니까?


답변

다중 코어에 병렬 LINQ를 사용하면 성능이 향상 될 수 있습니다. 병렬 LINQ (PLINQ) (MSDN)를 참조하십시오 .


답변

이 질문에 관심이있어서 방금 테스트를했습니다. .NET Framework 4.5.2를 Intel (R) Core (TM) i3-2328M CPU @ 2.20GHz, 2200Mhz, 2 코어 (Microsoft Windows 7 Ultimate를 실행하는 8GB RAM)에서 사용.

LINQ가 각 루프보다 빠를 수 있습니다. 내가 얻은 결과는 다음과 같습니다.

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

여러분 중 일부가이 코드를 콘솔 앱에 복사하여 붙여넣고 테스트 할 수 있다면 흥미로울 것입니다. 객체 (Employee)로 테스트하기 전에 정수로 동일한 테스트를 시도했습니다. 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

}