LINQ 성능 FAQ
LINQ를 이해하려고합니다. 가장 신경 쓰이는 점은 구문을 더 잘 이해하더라도 표현력을 위해 무의식적으로 성능을 희생하고 싶지 않다는 것입니다.
'Effective LINQ'에 대한 정보 또는 책의 중앙 집중식 저장소가 있습니까? 실패하면 개인적으로 가장 좋아하는 고성능 LINQ 기술은 무엇입니까?
주로 LINQ to Objects에 관심이 있지만 LINQ to SQL 및 LINQ to XML에 대한 모든 제안도 물론 환영합니다. 감사.
LINQ가 내부적으로 수행하는 작업을 이해하는 것만으로도 성능 저하 여부를 알 수있는 충분한 정보를 얻을 수 있습니다.
다음은 LINQ가 성능에 도움이되는 간단한 예입니다. 다음과 같은 전형적인 구식 접근 방식을 고려하십시오.
List<Foo> foos = GetSomeFoos();
List<Foo> filteredFoos = new List<Foo>();
foreach(Foo foo in foos)
{
if(foo.SomeProperty == "somevalue")
{
filteredFoos.Add(foo);
}
}
myRepeater.DataSource = filteredFoos;
myRepeater.DataBind();
따라서 위의 코드는 두 번 반복되고 필터링 된 값을 보관하기 위해 두 번째 컨테이너를 할당합니다. 얼마나 낭비입니까! 비교 :
var foos = GetSomeFoos();
var filteredFoos = foos.Where(foo => foo.SomeProperty == "somevalue");
myRepeater.DataSource = filteredFoos;
myRepeater.DataBind();
이것은 한 번만 반복됩니다 (리피터가 바인드 될 때). 원래 컨테이너 만 사용합니다. filteredFoos
중간 열거 자일뿐입니다. 그리고 어떤 이유로 나중에 리피터를 바인딩하지 않기로 결정하면 아무것도 낭비되지 않습니다. 한 번도 반복하거나 평가하지 않습니다.
매우 복잡한 시퀀스 조작에 들어가면 LINQ의 고유 한 체이닝 및 지연 평가 사용을 활용하여 잠재적 으로 많은 것을 얻을 수 있습니다 . 다시 말하지만, 다른 것과 마찬가지로 실제로 무엇을하고 있는지 이해하는 것입니다.
내장 기술인 Linq에는 성능 장점과 단점이 있습니다. 확장 메서드 뒤에있는 코드는 .NET 팀에서 상당한 성능주의를 기울였으며 지연 평가를 제공 할 수 있다는 것은 일련의 개체에 대해 대부분의 조작을 수행하는 비용이 조작 된 집합이 필요한 더 큰 알고리즘에 분산된다는 것을 의미합니다. . 그러나 코드 성능을 만들거나 손상시킬 수있는 몇 가지 사항을 알아야합니다.
무엇보다도 Linq는 작업을 수행하는 데 필요한 시간이나 메모리를 마술처럼 절약하지 않습니다. 절대적으로 필요할 때까지 이러한 작업을 지연시킬 수 있습니다. OrderBy ()는 QuickSort를 수행하는데, 이는 사용자가 QuickSorter를 직접 작성했거나 적시에 List.Sort ()를 사용한 것처럼 nlogn 시간이 걸립니다. 따라서 쿼리를 작성할 때 Linq에 시리즈에 대해 무엇을 요청하는지 항상 염두에 두십시오. 조작이 필요하지 않은 경우이를 방지하기 위해 쿼리 또는 메소드 체인을 재구성하십시오.
마찬가지로 특정 작업 (정렬, 그룹화, 집계)에는 해당 작업이 수행되는 전체 집합에 대한 지식이 필요합니다. 시리즈의 마지막 요소는 작업이 반복자에서 반환해야하는 첫 번째 요소 일 수 있습니다. 게다가 Linq 작업은 소스 열거 형을 변경해서는 안되지만 사용하는 많은 알고리즘 (즉, 내부 정렬)이 가능하기 때문에 이러한 작업은 평가할뿐만 아니라 전체 열거 형을 구체적이고 유한 한 구조로 복사합니다. , 작업을 수행하고 그것을 통해 양보합니다. 따라서 명령문에서 OrderBy ()를 사용하고 최종 결과에서 요소를 요청하면 주어진 IEnumerable이 생성 할 수있는 모든 것이 평가되고 메모리에 배열로 저장되고 정렬 된 다음 하나의 요소를 반환합니다. 시각. 교훈은,
마지막으로 Linq 메서드는 시스템의 호출 스택 크기와 메모리 공간을 크게 증가시킵니다. 전체 집합을 알아야하는 각 작업은 마지막 요소가 반복 될 때까지 전체 소스 집합을 메모리에 유지하고 각 요소의 평가에는 체인 또는 절에있는 메서드 수의 최소 두 배 깊이의 호출 스택이 포함됩니다. 인라인 문에서 (각 반복기의 MoveNext () 호출 또는 GetEnumerator 생성 및 각 람다에 대한 적어도 하나의 호출). 이것은 단순히 동일한 조작을 수행하는 지능적으로 엔지니어링 된 인라인 알고리즘보다 크고 느린 알고리즘을 초래할 것입니다. Linq의 주요 장점은 코드 단순성입니다. 그룹 값 목록의 사전을 생성하고 정렬하는 것은 이해하기 쉬운 코드가 아닙니다. 마이크로 최적화는 더 복잡하게 만들 수 있습니다. 성능이 주요 관심사라면 Linq를 사용하지 마십시오. 약 10 %의 시간 오버 헤드와 목록을 직접 조작하는 메모리 오버 헤드의 몇 배를 추가합니다. 그러나 유지 관리는 일반적으로 개발자의 주요 관심사이며 Linq는 확실히 도움이됩니다.
성능 킥 : 알고리즘의 성능이 성스럽고 타협 할 수없는 최우선 순위라면 C ++와 같은 관리되지 않는 언어로 프로그래밍 할 것입니다. .NET은 JIT 네이티브 컴파일, 관리 메모리 및 추가 시스템 스레드를 사용하여 관리되는 런타임 환경이기 때문에 훨씬 느려질 것입니다. 나는 그것이 "충분히 좋다"는 철학을 채택 할 것이다. Linq는 본질적으로 속도 저하를 유발할 수 있지만 차이를 알 수없고 고객이 차이를 알 수없는 경우 모든 실제 목적에 차이가 없습니다. "조기 최적화는 모든 악의 근원입니다"; 당신과 당신의 고객이 충분히 좋다는 것에 동의 할 때까지 그것을 작동하게하고, 그 후에 더 성능을 발휘할 기회를 찾으십시오. 항상 "더 좋을"수 있지만 기계 코드를 직접 포장하고 싶지 않다면
성능에 영향을 미치는 다양한 요인이 있습니다.
종종 LINQ를 사용하여 솔루션을 개발하면 시스템이 쿼리를 작성하는 동안 실제로 쿼리를 실행하지 않고도 쿼리를 나타내는 식 트리를 작성할 수 있기 때문에 상당히 합리적인 성능을 제공합니다. 결과를 반복 할 때만이 표현식 트리를 사용하여 쿼리를 생성하고 실행합니다.
절대적인 효율성 측면에서 미리 정의 된 저장 프로 시저에 대해 실행하면 약간의 성능 저하를 볼 수 있지만 일반적으로 취할 방법은 합리적인 성능 (예 : LINQ)을 제공하고 몇 퍼센트 손실에 대해 걱정하지 않는 시스템을 사용하여 솔루션을 개발하는 것입니다. 성능. 쿼리가 느리게 실행되는 경우 최적화를 살펴 봅니다.
현실은 대부분의 쿼리가 LINQ를 통해 수행되는 데 사소한 문제가 없다는 것입니다. 다른 사실은 쿼리가 느리게 실행되는 경우 쿼리 자체보다 인덱싱, 구조 등에 문제가있을 가능성이 더 높기 때문에 최적화하려는 경우에도 LINQ를 건드리지 않는 경우가 많습니다. 작동하는 데이터베이스 구조.
For handling XML, if you've got a document being loaded and parsed into memory (like anything based on the DOM model, or an XmlDocument or whatever), then you'll get more memory usage than systems that do someting like raising events to indicate finding a start or end tag, but not building a complete in-memory version of the document (like SAX or XmlReader). The downside is that the event-based processing is generally rather more complex. Again, with most documents there won't be a problem - most systems have several GB of RAM, so taking up a few MB representing a single XML document is not a problem (and you often process a large set of XML documents at least somewhat sequentially). It's only if you have a huge XML file that would take up 100's of MB that you worry about the particular choice.
Bear in mind that LINQ allows you to iterate over in-memory lists and so on as well, so in some situations (like where you're going to use a set of results again and again in a function), you may use .ToList or .ToArray to return the results. Sometimes this can be useful, although generally you want to try to use the database's querying rather in-memory.
As for personal favourites - NHibernate LINQ - it's an object-relational mapping tool that allows you to define classes, define mapping details, and then get it to generate the database from your classes rather than the other way round, and the LINQ support is pretty good (certainly better than the likes of SubSonic).
In linq to SQL you don't need to care that much about performance. you can chain all your statements in the way you think it is the most readable. Linq just translates all your statements into 1 SQL statement in the end, which only gets called/executed in the end (like when you call a .ToList()
a var
can contain this statement without executing it if you want to apply various extra statements in different conditions. The executing in the end only happens when you want to translate your statements into a result like an object or a list of objects.
There's a codeplex project called i4o which I used a while back which can help improve the performance of Linq to Objects in cases where you're doing equality comparisons, e.g.
from p in People
where p.Age == 21
select p;
http://i4o.codeplex.com/ I haven't tested it with .Net 4 so can't safely say it will still work but worth checking out. To get it to work its magic you mostly just have to decorate your class with some attributes to specify which property should be indexed. When I used it before it only works with equality comparisons though.
참고URL : https://stackoverflow.com/questions/4044400/linq-performance-faq
'programing tip' 카테고리의 다른 글
C #에서 큰 따옴표와 작은 따옴표의 차이점은 무엇입니까? (0) | 2020.11.30 |
---|---|
Eclipse Index 정리, 코드와 동기화되지 않음 (0) | 2020.11.30 |
Visual Studio가 변경 내용을 추적하지 않거나 편집 할 때 소스 제어에서 파일을 체크 아웃하지 않습니다. (0) | 2020.11.30 |
http.ListenAndServe () 중지 방법 (0) | 2020.11.30 |
클릭 할 때 페이지가 "점프"되지 않도록 빈 HTML 앵커를 만들려면 어떻게해야합니까? (0) | 2020.11.30 |