IEnumberable vs List - 사용방법그들은 어떻게 일하는가?
나는 열거자와 LINQ가 어떻게 기능하는지 의심스럽다.다음 두 가지 간단한 선택을 고려합니다.
List<Animal> sel = (from animal in Animals
join race in Species
on animal.SpeciesKey equals race.SpeciesKey
select animal).Distinct().ToList();
또는
IEnumerable<Animal> sel = (from animal in Animals
join race in Species
on animal.SpeciesKey equals race.SpeciesKey
select animal).Distinct();
일반적인 예처럼 보이도록 원래 개체의 이름을 변경했습니다.쿼리 자체는 그다지 중요하지 않습니다.제가 묻고 싶은 것은 다음과 같습니다.
foreach (Animal animal in sel) { /*do stuff*/ }
IEnumerable
sel Key Selector ter 、 ner sel sel 、 ner sel 、 ter sel 、 sel sel " Key Selector 、 outer Key Selector 。2번입니다. ' 인스턴스가요.내부" 멤버는 "동물" 인스턴스가 아니라 "종" 인스턴스가 있는데, 그것은 저에게 매우 낯설었습니다."외부" 멤버에는 "동물" 인스턴스가 포함되어 있습니다.어떤 것이 들어가고 어떤 것이 나오는지 두 명의 대표가 결정한다고 가정합니다.「Distinct」를 사용하면, 「inner」에는 6개의 항목이 포함되어 있습니다만(「Inner」에는 2개만이 「Distinct」이기 때문에 잘못되어 있습니다), 「outer」에는 올바른 값이 포함되어 있는 것을 알 수 있습니다.다시 한 번 말씀드리지만 위임된 방법에 따라 결정될 수 있지만 IEnumerable에 대해 제가 알고 있는 것보다 조금 더 많습니다.
가장 중요한 것은 두 가지 옵션 중 어떤 것이 퍼포먼스에 가장 적합한가?
list 변환: list를 evil list 변환:.ToList()
아니면 직접 열거자를 사용하는 건가요?
가능하다면 IEnumerable의 사용법을 설명하는 링크를 클릭해 주세요.
IEnumerable
에 동작을 나타냅니다.단, List는 그 동작을 구현한 것입니다.「 」를 사용하는 IEnumerable
컴파일러에게 작업을 나중에 연기할 수 있는 기회를 주고 그 과정에서 최적화할 수 있습니다.ToList()를 사용하는 경우 컴파일러가 결과를 즉시 다시 확인하도록 강제합니다.
" LINQ를 사용합니다.IEnumerable
동작을 지정하는 것만으로 LINQ에 평가를 미루고 프로그램을 최적화할 수 있는 기회를 주기 때문입니다.LINQ가 데이터베이스를 열거할 때까지 SQL을 생성하지 않는 것을 기억하십니까?이치노
public IEnumerable<Animals> AllSpotted()
{
return from a in Zoo.Animals
where a.coat.HasSpots == true
select a;
}
public IEnumerable<Animals> Feline(IEnumerable<Animals> sample)
{
return from a in sample
where a.race.Family == "Felidae"
select a;
}
public IEnumerable<Animals> Canine(IEnumerable<Animals> sample)
{
return from a in sample
where a.race.Family == "Canidae"
select a;
}
이제 초기 샘플("AllSpoted")과 일부 필터를 선택하는 방법이 있습니다.이제 다음을 수행할 수 있습니다.
var Leopards = Feline(AllSpotted());
var Hyenas = Canine(AllSpotted());
over List over를 요?IEnumerable
? 쿼리가 두 번 이상 실행되지 않도록 하는 경우에만 해당됩니다.하지만 전체적으로 더 나은가요?위의 경우 Leopards와 Hyenas는 각각 단일 SQL 쿼리로 변환되며 데이터베이스는 관련된 행만 반환합니다.하지만 만약 우리가 다음에서 목록을 돌려줬다면AllSpotted()
데이터베이스가 실제로 필요한 것보다 훨씬 더 많은 데이터를 반환할 수 있기 때문에 클라이언트의 필터링을 실시하면 사이클이 낭비되기 때문에 동작 속도가 느려질 수 있습니다.
프로그램에서는 마지막까지 목록으로 변환하는 것을 미루는 것이 더 나을 수 있으므로 Leopards와 Hyenas를 통해 여러 번 열거할 경우 다음과 같이 하겠습니다.
List<Animals> Leopards = Feline(AllSpotted()).ToList();
List<Animals> Hyenas = Canine(AllSpotted()).ToList();
Claudio Bernasconi의 TechBlog가 쓴 매우 좋은 기사가 여기 있습니다.IEnumerable, ICOlection, IList 및 List를 사용하는 경우
시나리오와 기능에 관한 몇 가지 기본적인 포인트를 다음에 나타냅니다.
「」를 실장하는 .IEnumerable
하면 '어울리지 않다'를 할 수 있습니다.foreach
구문을 사용합니다.
기본적으로 컬렉션의 다음 아이템을 얻을 수 있는 방법이 있습니다.몇 있는지 알 수.foreach
다 떨어질 때까지 다음 아이템을 계속 얻을 수 있습니다.
이것은 예를 들어 대규모 데이터베이스 테이블에서 행 처리를 시작하기 전에 전체 내용을 메모리에 복사하지 않는 경우 등 특정 상황에서 매우 유용합니다.
, 이제List
를 실장하다IEnumerable
memory. 내의 전체 .「 」가 IEnumerable
'아예'라고 부르면.ToList()
열거의 내용을 메모리에 저장하여 새 목록을 만듭니다.
되며, 으로는 linq 식에서 linq를 할 때 이됩니다.foreach
A . ANIEnumerable
은 linq를 할 때 됩니다.foreach
, 더할 수 있습니다..ToList()
.
제 말은 이렇습니다.
var things =
from item in BigDatabaseCall()
where ....
select item;
// this will iterate through the entire linq statement:
int count = things.Count();
// this will stop after iterating the first one, but will execute the linq again
bool hasAnyRecs = things.Any();
// this will execute the linq statement *again*
foreach( var thing in things ) ...
// this will copy the results to a list in memory
var list = things.ToList()
// this won't iterate through again, the list knows how many items are in it
int count2 = list.Count();
// this won't execute the linq statement - we have it copied to the list
foreach( var thing in list ) ...
아무도 한가지 중요한 차이점을 언급하지 않았고 아이러니하게도 이것을 복제한 것으로 종결된 질문에 답변했다.
IENumerable은 읽기 전용이며 List는 읽기 전용이 아닙니다.
목록과 IENumerable의 실제 차이를 참조하십시오.
가장 중요한 것은 Linq를 사용하면 쿼리가 즉시 평가되지 않는다는 것입니다.인 과과 the the the the the the the the the the the the를 통해 됩니다.IEnumerable<T>
in a a a a foreach
모든 이상한 대표들이 그렇게 하고 있다.
첫 에서는 "조회"를 호출하여 합니다.ToList
이치노
는 '하다'입니다.IEnumerable<T>
나중에 쿼리를 실행하는 데 필요한 모든 정보가 포함되어 있습니다.
성능 측면에서는 정답은 상황에 따라 다릅니다.결과를 한 번에 평가해야 하는 경우(예를 들어 나중에 쿼리할 구조를 변환하는 경우 등) 또는 데이터 전송에 대한 반복을 원하지 않는 경우IEnumerable<T>
이데올로기보다 이외의 경우는, 「」를 합니다.IEnumerable<T>
디폴트로는 두 번째 예에서는 온디맨드 평가를 사용해야 합니다.이는 결과를 목록에 저장해야 하는 특별한 이유가 없는 한 일반적으로 메모리 사용량이 적기 때문입니다.
IEnumerable의 장점은 실행이 지연된다는 것입니다(일반적으로 데이터베이스 사용).실제로 데이터를 루프할 때까지 쿼리는 실행되지 않습니다.필요할 때까지 기다리는 쿼리입니다(일명 게으른 로딩).
ToList에 전화를 걸면 쿼리가 실행되거나 제가 말하고 싶은 것처럼 "실현화"됩니다.
둘 다 장단점이 있다.ToList를 호출하면 쿼리가 언제 실행되는지 알 수 없는 문제가 해소될 수 있습니다.IEnumerable을 고수하면 프로그램이 실제로 필요할 때까지 아무런 작업도 하지 않는다는 이점을 얻을 수 있습니다.
어느 날 제가 빠져든 잘못된 개념을 공유하겠습니다.
var names = new List<string> {"mercedes", "mazda", "bmw", "fiat", "ferrari"};
var startingWith_M = names.Where(x => x.StartsWith("m"));
var startingWith_F = names.Where(x => x.StartsWith("f"));
// updating existing list
names[0] = "ford";
// Guess what should be printed before continuing
print( startingWith_M.ToList() );
print( startingWith_F.ToList() );
예상 결과
// I was expecting
print( startingWith_M.ToList() ); // mercedes, mazda
print( startingWith_F.ToList() ); // fiat, ferrari
실제 결과
// what printed actualy
print( startingWith_M.ToList() ); // mazda
print( startingWith_F.ToList() ); // ford, fiat, ferrari
설명.
다른 답변과 마찬가지로 결과에 대한 평가는 전화할 때까지 연기되었습니다.ToList
예: " " " )을 사용합니다.ToArray
.
이 경우 코드를 다음과 같이 다시 쓸 수 있습니다.
var names = new List<string> {"mercedes", "mazda", "bmw", "fiat", "ferrari"};
// updating existing list
names[0] = "ford";
// before calling ToList directly
var startingWith_M = names.Where(x => x.StartsWith("m"));
var startingWith_F = names.Where(x => x.StartsWith("f"));
print( startingWith_M.ToList() );
print( startingWith_F.ToList() );
정렬하여 재생
만으로 할 수 있는 는, 「」를 해 주세요.IEnumerable
.
되어 있는 하는 것은 이 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」라고 것이 좋습니다.ToList
번째,의 각 에 대해 새로운 되고, 이 목록 요소가 작성되며, 이 목록 에는 저, 것, 것, 이, 이, 이, 이, first, first, first, first, first, first first, 。IEnumerable
한 이 떨어지지만 할 수 . 그러나 때로는 더 안전하며 때로는List
메서드는 (랜덤액세스 등) 편리합니다.
위에 게시된 모든 답변에 덧붙여, 여기 제 의견이 있습니다.ICOLection, ArrayList 등의 IEnumberable을 실장하는 타입은 List 이외에도 많이 있습니다.따라서 IEnumerable이 어떤 메서드의 파라미터로 설정되어 있으면 어떤 컬렉션 타입도 함수에 전달할 수 있습니다.즉, 특정 구현이 아닌 추상화에 대해 작업하는 방법을 가질 수 있다.
의은 IEnumerable(IEnumerable(IE Numerable)(IE Numerable(IE Numerable)(IE Numerable(IE Numerable)(IE Numerable(IE Numberable)))을 호출할 까지의 단점이 ..ToList()
목록이 변경될 수 있습니다., .
var persons;
using (MyEntities db = new MyEntities()) {
persons = db.Persons.ToList(); // It's mine now. In the memory
}
// do what you want with the list of persons;
그리고 이것은 작동하지 않을 것이다.
IEnumerable<Person> persons;
using (MyEntities db = new MyEntities()) {
persons = db.Persons; // nothing is brought until you use it;
}
persons = persons.ToList(); // trying to use it...
// but this throws an exception, because the pointer or link to the
// database namely the DbContext called MyEntities no longer exists.
IEnumerable을 목록으로 변환할 수 없는 경우(무제한 목록이나 매우 큰 목록 등)가 많습니다.가장 명백한 예는 모든 소수, 페이스북 사용자, 세부사항 또는 ebay 상의 모든 아이템이다.
차이점은 "List" 객체는 "지금 바로 여기에" 저장되지만, "IEnumberable 객체는 "한 번에 1개만".ebay의 모든 아이템을 살펴본다면 작은 컴퓨터도 한 번에 하나씩 처리할 수 있을 것입니다.ToList()"는 아무리 큰 컴퓨터라도 메모리가 부족할 것입니다.어떤 컴퓨터도 혼자서는 이렇게 많은 양의 데이터를 저장하고 처리할 수 없습니다.
[편집] - 말할 필요도 없이 '이것도 저것도'가 아닙니다.같은 클래스에 리스트와 IE넘버블을 모두 사용하는 것이 좋습니다.정의상 무한한 양의 메모리가 필요하기 때문에 세상의 어떤 컴퓨터도 모든 소수를 나열할 수 없었다. 쉽게 수 요.class PrimeContainer
에는 ''가 포함되어 있습니다.IEnumerable<long> primes
명백한 이유로, 이것은 또한 다음을 포함합니다.SortedList<long> _primes
에됩니다.확인할 다음 소수는 기존 소수점(제곱근까지)에 대해서만 구한다.이렇게 하면 한 번에 하나씩 소수점(IEnumerable)과 "지금까지의 소수점" 목록을 얻을 수 있습니다. 이는 전체(무한) 목록의 근사치입니다.
언급URL : https://stackoverflow.com/questions/3628425/ienumerable-vs-list-what-to-use-how-do-they-work
'programing' 카테고리의 다른 글
Panda DataFrame은 다음 문자열로 목록을 저장했습니다.목록으로 다시 변환하는 방법 (0) | 2023.04.10 |
---|---|
Swift에서 두 날짜(월/일/시간/분/초)의 차이 파악 (0) | 2023.04.10 |
Apple 프로덕션 푸시 SSL 인증서를 .p12 형식으로 내보낼 수 없습니다. (0) | 2023.04.10 |
어플리케이션은 어디에 있습니까?WPF의 DoEvents()? (0) | 2023.04.10 |
스와이프를 추가하여 UITable View Cell 삭제 (0) | 2023.04.10 |