C # ArrayList과 의 차이점은 무엇입니까 List<>?
그렇지 않은 List<>유형 만 ArrayList있습니까?
List<>일반적으로 물어 보는 반면에, List<object>구체적으로 묻습니다
C # ArrayList과 의 차이점은 무엇입니까 List<>?
그렇지 않은 List<>유형 만 ArrayList있습니까?
List<>일반적으로 물어 보는 반면에, List<object>구체적으로 묻습니다
답변:
그렇습니다. List<T>일반 클래스입니다. 캐스팅하거나 캐스팅하지 않고 특정 유형의 값을 저장할 수 있습니다 object( T이 경우 값 유형 인 경우 boxing / unboxing 오버 헤드가 발생 함 ArrayList). ArrayList단순히 object참조 를 저장 합니다. 일반 컬렉션으로서 List<T>일반 IEnumerable<T>인터페이스를 구현하며 LINQ에서 쉽게 사용할 수 있습니다 ( Cast또는 OfType호출 하지 않아도 됨 ).
ArrayListC #에 제네릭이 없었던 날에 속합니다. 에 찬성하여 더 이상 사용되지 않습니다 List<T>. 당신은 사용하지 말아야 ArrayList새로운 코드에 그 목표 .NET> = 2.0 오래된 API와 인터페이스해야하지 않는 한 그것은 그.
ArrayList런타임 과 사실상 동일 합니다. 그러나 정적으로는로 캐스팅해야합니다 ArrayList.
사용 List<T>당신은 오류를 캐스팅 방지 할 수 있습니다. 런타임 캐스팅 오류 를 피하는 것이 매우 유용합니다 .
예:
여기서 (를 사용하여 ArrayList)이 코드를 컴파일 할 수 있지만 나중에 실행 오류가 표시됩니다.
ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
total += num; //-->Runtime Error
}
를 사용 List하면 다음 오류를 피할 수 있습니다.
List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
total += num;
}
참조 : MSDN
위의 포인트에 추가합니다. 사용하여 ArrayList64 비트 운영 시스템은 32 비트 운영체제에서 사용하는 것보다 2 배의 메모리 걸린다. 한편, 일반 목록 List<T>은보다 적은 메모리를 사용합니다 ArrayList.
예를 들어 ArrayList32 비트에서 19MB를 사용하는 경우 64 비트에서 39MB가 필요합니다. 그러나 List<int>32 비트 의 일반 8MB 목록이있는 경우 64 비트의 경우 8.1MB 만 사용되므로 ArrayList와 비교할 때 481 %의 차이가 있습니다.
추가해야 할 또 다른 차이점은 스레드 동기화와 관련이 있습니다.
ArrayList컬렉션 주위의 스레드 안전 래퍼를 반환하는 Synchronized 속성을 통해 스레드 안전을 제공합니다. 랩퍼는 모든 추가 또는 제거 조작에서 전체 콜렉션을 잠그면 작동합니다. 따라서 컬렉션에 액세스하려는 각 스레드는 해당 차례가 하나의 잠금을 수행 할 때까지 기다려야합니다. 이는 확장 할 수 없으며 대규모 컬렉션의 경우 성능이 크게 저하 될 수 있습니다.
List<T>스레드 동기화를 제공하지 않습니다. 사용자 코드는 여러 스레드에서 동시에 항목을 추가하거나 제거 할 때 모든 동기화를 제공해야합니다.
자세한 내용 은 .Net Framework의 스레드 동기화
ArrayList피할 수 있다면 사용해야한다고 말하는 것은 아니지만 이것이 어리석은 이유입니다. 래퍼는 전적으로 선택 사항입니다. 잠금이 필요하지 않거나 더 세밀한 제어가 필요한 경우 래퍼를 사용하지 마십시오.
간단한 대답은
ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();
arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());
list.Add(1);
list.Add("String"); // Compile-time Error
list.Add(new object()); // Compile-time Error
Microsoft 공식 문서를 읽으십시오 : https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/
참고 : 차이점을 이해하기 전에 Generics를 알아야합니다. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
ArrayList서로 다른 유형의 데이터를 List<>수집 하는 반면 유사한 유형의 자체 depedencties를 수집합니다.
성능은 이미 몇 가지 답변에서 차별화 요소로 언급되었지만“ 어느 정도 느린 ArrayList가요? ”및“ 왜 전체적으로 느려 집니까? ”, 아래를보세요.
값 유형이 요소로 사용될 때마다 성능이 크게 저하됩니다 ArrayList. 단순히 요소를 추가하는 경우를 고려하십시오. 권투가 계속 진행됨에 따라 ArrayListAdd는 object매개 변수 만 사용 하므로 가비지 수집기는보다 많은 작업을 수행하도록 트리거됩니다 List<T>.
시차는 얼마입니까? 보다 몇 배 이상 느립니다 List<T>. 10mil int 값을 ArrayListvs에 추가하는 코드에서 발생하는 일을 살펴보십시오 List<T>.

'Mean'열에서 노란색으로 강조 표시된 런타임 차이는 5 배 입니다. 또한 각각에 대해 수행 된 가비지 콜렉션 수의 차이가 빨간색으로 강조 표시됩니다 (GC / 1000 실행 없음).
프로파일 러를 사용하여 진행 상황을 신속하게 확인 하면 실제로 요소를 추가하는 대신 대부분의 시간이 GC를 수행하는 데 소요 됩니다. 아래의 갈색 막대는 가비지 콜렉터 활동 차단을 나타냅니다.

위의 ArrayList시나리오에서 진행되는 작업에 대한 자세한 분석은 https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/에서 작성했습니다 .
Jeffrey Richter의“CLR via C #”에서도 비슷한 결과가 나옵니다. 12 장 (일반) :
[…] 컴퓨터에서이 프로그램의 릴리스 빌드 (최적화가 설정된 상태)를 컴파일하고 실행할 때 다음과 같은 결과가 나타납니다.
00 : 00 : 01.6246959 (GCs = 6) List <Int32>
00 : 00 : 10.8555008 (GCs = 390) Int32의
배열 목록 00 : 00 : 02.5427847 (GCs = 4) List <String>
00 : 00 : 02.7944831 (GCs = 7 ) 문자열의 ArrayList여기서 출력은 Int32 유형으로 일반 목록 알고리즘을 사용하는 것이 Int32와 함께 제네릭이 아닌 ArrayList 알고리즘을 사용하는 것보다 훨씬 빠르다는 것을 보여줍니다. 실제로, 그 차이는 놀랍습니다 : 1.6 초 대 거의 11 초. ~ 7 배 빠릅니다 ! 또한 ArrayList에 값 유형 (Int32)을 사용하면 많은 복싱 작업이 발생하여 390 개의 가비지 수집이 발생합니다. 한편, List 알고리즘에는 6 개의 가비지 콜렉션이 필요했습니다.
나는 사이의 차이를 생각 ArrayList하고 List<T>있습니다 :
List<T>여기서 T는 value-type보다 빠릅니다 ArrayList. 이것은 List<T>boxing / unboxing을 피하기 때문입니다 (여기서 T는 value-type입니다).ArrayList이전 버전과의 호환성을 위해서만 사용됩니다. (실제 차이는 없지만 중요한 메모라고 생각합니다).ArrayList을 사용 하면 반사가 더 쉽습니다.List<T>ArrayListIsSynchronized속성 이 있습니다. 따라서 syncronised를 쉽게 만들고 사용할 수 있습니다 ArrayList. 에 IsSynchronized대한 속성을 찾지 못했습니다 List<T>. 또한 이러한 유형의 동기화는 상대적으로 비효율적입니다 ( msdn ).
var arraylist = new ArrayList();
var arrayListSyncronized = ArrayList.Synchronized(arraylist
Console.WriteLine($"syncronized {arraylist.IsSynchronized}");
Console.WriteLine($"syncronized {arrayListSyncronized.IsSynchronized}");
var list = new List<object>();
var listSyncronized = ArrayList.Synchronized(list);
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such propArrayList보유 ArrayList.SyncRootsyncronisation (사용할 수있는 속성 은 MSDN ). 속성 List<T>이 없으므로 SyncRoot다음 구성에서는 사용하는 경우 일부 객체를 사용해야합니다 List<T>.
ArrayList myCollection = new ArrayList();
lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal
{
foreach (object item in myCollection)
{
// ...
}
}.NET Framework 설명서 에서 언급 한 바와 같이
ArrayList새로운 개발에 클래스를 사용하지 않는 것이 좋습니다 . 대신 일반List<T>클래스 를 사용하는 것이 좋습니다 . 이ArrayList클래스는 이기종 객체 컬렉션을 보유하도록 설계되었습니다. 그러나 항상 최상의 성능을 제공하는 것은 아닙니다. 대신 다음을 권장합니다.
- 이기종 개체 컬렉션의 경우
List<Object>(C #) 또는List(Of Object)(Visual Basic) 형식을 사용하십시오.- 동종의 객체 컬렉션을 위해서는
List<T>클래스를 사용하십시오 .
"목록"을 사용하면 전송 오류를 방지 할 수 있습니다. 런타임 캐스팅 오류를 피하는 것이 매우 유용합니다.
예:
여기서 (ArrayList를 사용하여)이 코드를 컴파일 할 수 있지만 나중에 실행 오류가 표시됩니다.
// Create a new ArrayList
System.Collections.ArrayList mixedList = new System.Collections.ArrayList();
// Add some numbers to the list
mixedList.Add(7);
mixedList.Add(21);
// Add some strings to the list
mixedList.Add("Hello");
mixedList.Add("This is going to be a problem");
System.Collections.ArrayList intList = new System.Collections.ArrayList();
System.Collections.ArrayList strList = new System.Collections.ArrayList();
foreach (object obj in mixedList)
{
if (obj.GetType().Equals(typeof(int)))
{
intList.Add(obj);
}
else if (obj.GetType().Equals(typeof(string)))
{
strList.Add(obj);
}
else
{
// error.
}
}
귀하의 데이터를 아는 것에 대한 모든 것. 효율성을 기준으로 코드를 계속 확장하려면 유형, 특히 '사용자 정의 유형'에 대해 항상 궁금해하는 불필요한 단계없이 데이터를 해독하는 방법으로 목록 옵션을 선택해야합니다. 기계가 그 차이를 이해하고 실제로 처리하고있는 데이터 유형이 무엇인지 판단 할 수 있다면 왜 'IF THEN ELSE'결정의 진행을 통해 방해가됩니까? 저의 철학은 기계 작업을하는 대신 기계를 작동시키는 것입니까? 다른 객체 코드 명령의 고유 한 차이점을 아는 것은 코드를 효율적으로 만드는 데 큰 도움이됩니다.
톰 존슨 (하나의 입구 ... 하나의 출구)