프로그래밍/C#

배열[], ArrayList, List<T> 의 각 기능과 차이점

selinatsu 2024. 10. 3. 10:52
반응형

모두 여러 개의 데이타를 저장하고 관리하는 기능을 제공하는 자료구조로 기본적인 목적은 유사하다.

다만 몇가지 중요한 차이점이 있기 때문에 장, 단점을 살펴 상황에 맞게 사용하면 된다.

 

배열 [ ] 

 

* 고정 크기

 - 배열은 생성할 때 크기가 고정되며, 생성 후에는 크기를 변경할 수 없습니다.

* 타입 지정 

 - 배열은 특정 타입의 데이터를 저장할 수 있습니다. 예를 들어, int[]는 정수만 저장할 수 있습니다.

* 빠른 접근 :

 - 배열은 메모리 상에서 연속된 공간을 사용하기 때문에 인덱스를 통해 빠르게 데이터에 접근할 수 있습니다.

 

 

int[] numbers = new int[3]; // 크기가 3인 배열 생성
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;


 

ArrayList : 기본 제공 컬렉션 (System.Collections)

* 가변 크기

 - ArrayList는 배열과 달리 크기가 동적으로 변할 수 있습니다.

 - 데이터를 추가하거나 제거할 수 있으며, 크기는 자동으로 조정됩니다.

* 타입 비안전성

 - ArrayList는 모든 타입의 객체를 저장할 수 있습니다.

 - 즉, 정수, 문자열 등 다양한 타입을 저장할 수 있지만, 이로 인해 런타임 오류가 발생할 수 있습니다.

 - 저장된 데이터를 꺼낼 때 올바른 타입으로 캐스팅해야 합니다.

* 성능

 - 제네릭 컬렉션에 비해 성능이 낮을 수 있습니다.

 - 타입이 섞일 수 있어 캐스팅 비용이 발생하고, 타입 검사나 오류가 런타임에만 이루어지기 때문입니다.

 

ArrayList arrayList = new ArrayList();
arrayList.Add(1);      // 정수 추가
arrayList.Add("two");  // 문자열 추가
int number = (int)arrayList[0]; // 타입 캐스팅 필요


 

List<T> : 제네릭 컬렉션 (System.Collections.Generic)

* 가변 크기

 - List<T>도 ArrayList처럼 크기가 동적으로 변할 수 있습니다.

 - 데이터를 추가하거나 제거할 수 있으며, 크기는 자동으로 조정됩니다.

* 타입 안전성

 - List<T>는 제네릭을 사용하여, 특정 타입(T)만 저장할 수 있습니다.

 - 예를 들어, List<int>는 정수만 저장할 수 있습니다.

 - 덕분에 컴파일 타임에 타입 오류를 잡아낼 수 있고, 런타임 캐스팅 오류가 없습니다.

* 성능

 - ArrayList에 비해 타입 안전성을 제공하기 때문에 더 효율적이며, 타입 캐스팅에 따른 성능 손실이 없습니다.

 

List<int> numbers = new List<int>();
numbers.Add(1);  // 정수 추가
numbers.Add(2);  // 정수 추가

 


 

주요 차이점 요약

기능/특징 배열 [] ArrayList List
크기 고정 가변 가변
타입 안전성 있음 없음 있음
저장할 수 있는 타입 한 가지 타입 여러 타입 한 가지 타입(T)
타입 캐스팅 불필요 필요 불필요
성능 빠름 느림 (캐스팅 비용) 빠름

 

정리하면...

* 배열

 - 크기가 고정되고 한 가지 타입만 저장할 수 있지만, 빠르고 메모리 효율적입니다.

* ArrayList

 - 크기는 가변적이지만, 타입 안전성이 없고 캐스팅 비용이 발생할 수 있어 성능이나 안정성 측면에서 불리합니다.

* List<T>

 - 배열과 유사한 성능에 크기가 가변적이고 타입 안전성을 제공하므로, 일반적으로 가장 많이 사용되는 컬렉션입니다.

 

대부분의 경우, 타입 안정성과 성능을 고려하면 List<T>를 사용하는 것이 가장 적합합니다.

ArrayList는 호환성 문제나 특수한 상황이 아니라면 요즘에는 거의 사용되지 않습니다.

 


 

부가 설명1

ArrayList는 서로 다른 타입의 데이터를 한 리스트에 저장할 수 있습니다. 즉, 첫 번째 요소로 정수(int), 두 번째 요소로 문자열(string), 세 번째 요소로 float를 넣는 식으로 다양한 타입의 데이터를 동일한 ArrayList에 저장할 수 있습니다.


class Program
{
    static void Main()
    {
        ArrayList arrayList = new ArrayList();

        arrayList.Add(1);         // 정수(int) 추가
        arrayList.Add("hello");   // 문자열(string) 추가
        arrayList.Add(3.14f);     // 실수(float) 추가
    }
}

 

언뜻 보기에는 장점으로 보이나 타입 캐스팅에 따른 비용 발생, 그리고 그로 인한 안전성 이슈가 생기게 된다.

 


 

부가 설명2

게임 개발에서 배열([])과 List<T>의 성능 차이는 분명히 존재하지만, 그 차이가 크게 느껴질지는 게임의 규모와 특정 상황에 따라 달라집니다. 간단히 말해, 대부분의 일반적인 게임에서는 배열과 List<T>의 성능 차이가 눈에 띌 만큼 크지 않다고 볼 수 있습니다. 하지만 특정한 경우에는 이 차이가 더 두드러질 수 있습니다.

 

1. 성능 차이가 두드러질 때

* 매우 큰 데이터 세트

 - 만약 수십만 개 이상의 데이터를 다룬다면 배열과 List<T>의 성능 차이가 더 명확하게 나타날 수 있습니다. 배열은 고정 크기이며, 메모리 할당과 접근이 빠르기 때문에 이러한 대규모 데이터에서는 배열이 더 유리할 수 있습니다.

* 빈번한 크기 조정 

 - List<T>는 크기가 가변적이므로 데이터를 계속 추가하거나 삭제할 때 내부적으로 배열의 크기를 조정하고 재할당해야 합니다. 특히 많은 양의 데이터를 한꺼번에 추가하거나 삭제하는 경우에는 배열 복사와 같은 추가 비용이 발생할 수 있어 성능에 영향을 줄 수 있습니다.

* 초고성능 요구

 - FPS(초당 프레임 수)를 60 이상으로 유지해야 하는 고성능 게임에서, 배열과 List<T> 간의 작은 성능 차이도 최적화를 필요로 할 수 있습니다. 게임의 핵심 루프에서 자주 호출되는 경우(예: AI 처리, 물리 계산 등)에서는 배열이 미세하게 더 빠를 수 있습니다.

 

2. 성능 차이가 크지 않을 때

* 작은 데이터 세트

 - 만약 데이터 양이 적다면 배열과 List<T>의 성능 차이는 거의 느껴지지 않습니다. 일반적인 게임의 데이터 처리에서는 1,000개 이하의 객체나 요소를 다루는 경우가 많으며, 이런 상황에서는 둘의 차이가 매우 미미합니다.

* 일반적인 게임 로직

 - 일반적인 게임에서 데이터는 매 프레임마다 아주 많이 추가/삭제되기보다는 주로 읽거나 간헐적으로 업데이트됩니다. 이러한 경우에는 List<T>의 성능 손실은 거의 발생하지 않으며, 편리한 메서드와 유연성 덕분에 List<T>를 사용하는 것이 더 좋습니다.

 

3. 게임에서 어떤 상황에 배열이 더 유리할까?

* 정적 데이터

 - 맵 크기, 고정된 오브젝트나 게임 타일과 같이 데이터 크기가 고정되어 있고 변하지 않는다면 배열이 성능상 더 유리합니다.

* 빈번한 접근이 중요한 데이터

 - 배열은 인덱스를 통한 접근이 매우 빠르므로 매우 빈번하게 접근하는 데이터에서 배열이 더 효율적일 수 있습니다.

 

4. 게임에서 어떤 상황에 List<T>가 더 유리할까?

* 가변적 데이터

 - 적들이 계속 생성되거나 제거되는 등 동적으로 변화하는 데이터를 처리할 때 List<T>는 훨씬 유연하게 데이터를 관리할 수 있습니다.

* 데이터 추가 및 삭제

 - 게임에서 많은 데이터가 실시간으로 추가/삭제되는 경우 List<T>의 기능이 더 편리하고 관리하기 쉬워집니다.

* 일반적인 데이터 관리

 - List<T>는 Add(), Remove(), Contains()와 같은 메서드가 있어 데이터를 관리하는 데 매우 유용합니다.

 

5. 결론 : 성능 최적화 필요 여부

* 일반적인 경우

 - 대부분의 중소형 게임에서는 배열과 List<T> 간의 성능 차이가 거의 눈에 띄지 않으며, 게임 개발 생산성을 위해 List<T>를 사용하는 것이 더 일반적입니다. List<T>는 더 유연하고 관리가 쉬우며, 성능상 손실이 크게 발생하지 않기 때문입니다.

* 성능 최적화가 중요한 경우

 - 만약 게임의 핵심 시스템에서 매우 많은 데이터를 자주 처리하거나, 매 프레임마다 반복적으로 대량의 데이터를 처리해야 한다면 배열을 사용하는 것이 적합할 수 있습니다. 예를 들어, 물리 엔진, 렌더링 파이프라인 또는 AI 계산과 같은 부분에서는 배열을 사용하는 것이 더 나을 수 있습니다.

 

최종 결론

일반적으로 List<T>를 사용하는 것이 더 편리하고 유연하며, 성능상 크게 손실이 없기 때문에 게임 개발에서 List<T>를 더 자주 사용합니다. 그러나 특정한 고성능이 요구되거나, 고정된 크기의 대규모 데이터를 다뤄야 하는 경우 배열을 사용하는 것이 성능 최적화에 유리할 수 있습니다. 대부분의 경우 성능 차이는 크지 않으므로 코드의 가독성과 관리 측면에서 List<T>를 선호하는 추세입니다.

 

반응형

'프로그래밍 > C#' 카테고리의 다른 글

yield return  (0) 2024.10.04
배열 초기화  (0) 2024.10.04
for 와 foreach 비교  (1) 2024.10.03
int 와 Int32  (0) 2024.10.02
Property (프로퍼티)  (0) 2024.09.18