저는 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
루프를 사용하십시오 .
답변
다중 코어에 병렬 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
}
