2017-02-17 1 views
0

Built-in Arrays와 Lists와 같은 콜렉션이 어떻게 다른지에 대해 읽었으며 내장 배열이 Lists보다 훨씬 빠르다는 사실을 알게되었습니다 (특정 상황에서는 최대 7 배 더 빠름).Unity3D에서 최적화를 위해 가장 빠른 컬렉션을 사용 하시겠습니까?

그래서 내 질문은 완전하게 채우지 않고 대신 최대 값을 갖고 배열의 크기를 유지하기 위해 카운터 int를 사용하는 내장 된 배열을 사용하는 경우 List를 사용하는 것보다 훨씬 빠릅니까?

내가 중요한 이유는 내가 Node.js에서 처음부터 서버를 빌드하고 클라이언트의 라이브러리로 websockets-sharp를 사용 중이며 만기가되는 지연을보고있는 멀티 플레이어 게임입니다. (목록, 스택, 사전 및 대기열을 사용하여) 업데이트 기능을 수정하고 체크인해야하며, 바이트 [] 배열로 인해 성능이 향상 될지 궁금합니다.

P. 다음은 내가 약은 System.Collections 대 배열 성능에 내장에서 정보를 가지고있는 곳입니다 :

http://answers.unity3d.com/questions/38479/is-listt-as-fast-to-access-as-a-standard-array.html

Performance differences... so dramatic?

http://wiki.unity3d.com/index.php/Choosing_the_right_collection_type

+0

앱이 데이터를 추가하고 검색하는 방법에 따라 다릅니다. 한 번 쓰십시오? 읽기 전용입니까? 무작위 액세스? 추가 만 하시겠습니까? 무작위 삽입? – MickyD

+0

나는리스트를 사용하는 것과 같은 방법으로 배열을 사용하고 있는데, 현재 루프를 포함하고있는 아이템을 추가하고 제거하는 것으로 내용을 수정하고있다. –

+0

답변을 원하지만 자세한 내용이 필요합니다. Dictionary Vs List에 관한 질문은 어떻게 사용 하시겠습니까? 사용법은 두 가지를 비교하는 데있어 중요합니다. – Programmer

답변

3

는 는이 목록을 사용하는 것보다 훨씬 빠른 것?

.

나는 과거 Unity에서 실험을했는데, 이렇게하는 것은 이미지 처리와 같은 모든 프레임에서 반복 될 필요가있는 많은 양의 항목에 대해서는 완전히 괜찮습니다.

전 네트워크를 통해 HQ Image를 스트리밍하는 앱을 만들었습니다. List으로 만들기는 쉬웠지만 Array으로 전환하면 초당 수신 한 프레임 수가 증가했습니다.또한 메모리 할당량이입니다.

Array를 사용하는 유일한 단점은 항목을 담는 데 충분하다는 것을 확인하기 위해 많은 양의 메모리를 할당해야한다는 것입니다. 또한 배열에 넣으려는 현재 항목이 맞는지 확인해야합니다. 그렇지 않다면 더 큰 크기의 새 배열을 만든 다음 이전 데이터를 새 배열에 복사해야합니다.

유니티의 blog 또한 Update() 기능 개선 및 ArrayList을 사용 간의 상이한 성능을 도시하는 포스트를 갖는다. 실제로 성능이 크게 향상되었으며 해당 실험에서는 일 때 보다 빠르게 배열이 5x입니다.

유니티를 작업 할 때 나 자신에 대해 설정 한 규칙이며, 그것은 여전히 ​​오늘날에도 사실로 remians :을 통해 당신에게 루프를 필요로

당신이 큰 항목 (200K 이상)을 저장할 필요가 .If

1 모든 프레임, 배열 및 배열의 ​​길이를 결정하는 데 사용할 수있는 간단한 int 값을 사용하십시오. 이 .If

2는 의 크기에 대한 단지 항목입니다 만 가끔 다음 List을 사용하여 실행됩니다.

Unity에서 실행되는 this 코드가 수정되었습니다.

배열/대한 : 6726ms (-1295415896)

목록/대한 : 15803ms (-1295415896)

배열/foreach 문 : 8511ms (-1295415896)

목록/foreach는 : 42689ms (-1295415896)

차이점은 일반적인 C# 응용 프로그램과 달리 Unity에서 매우 중요합니다.

void Start() 
{ 
    List<int> list = new List<int>(6000000); 
    for (int i = 0; i < 6000000; i++) 
    { 
     list.Add(UnityEngine.Random.Range(1, 10)); 
    } 
    int[] arr = list.ToArray(); 

    int chk = 0; 
    Stopwatch watch = Stopwatch.StartNew(); 
    for (int rpt = 0; rpt < 100; rpt++) 
    { 
     int len = list.Count; 
     for (int i = 0; i < len; i++) 
     { 
      chk += list[i]; 
     } 
    } 
    watch.Stop(); 
    UnityEngine.Debug.Log(String.Format("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk)); 

    chk = 0; 
    watch = Stopwatch.StartNew(); 
    for (int rpt = 0; rpt < 100; rpt++) 
    { 
     int len = arr.Length; 
     for (int i = 0; i < len; i++) 
     { 
      chk += arr[i]; 
     } 
    } 
    watch.Stop(); 
    UnityEngine.Debug.Log(String.Format("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk)); 

    chk = 0; 
    watch = Stopwatch.StartNew(); 
    for (int rpt = 0; rpt < 100; rpt++) 
    { 
     foreach (int i in list) 
     { 
      chk += i; 
     } 
    } 
    watch.Stop(); 
    UnityEngine.Debug.Log(String.Format("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk)); 

    chk = 0; 
    watch = Stopwatch.StartNew(); 
    for (int rpt = 0; rpt < 100; rpt++) 
    { 
     foreach (int i in arr) 
     { 
      chk += i; 
     } 
    } 
    watch.Stop(); 
    UnityEngine.Debug.Log(String.Format("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk)); 
} 
+1

사이드 노트 : "메모리 할당이 제거되었습니다."실제 코드가 훨씬 빨라진 실제 이유입니다 (액세스 비용의 2 배 차이가 각 항목을 처리하는 데 드는 비용에 빠지기 쉽습니다). 미리 할당 된리스트를'List.Clear'와 재사용함으로써 비슷한 이점을 얻을 수 없었던 이유는 없습니다 ... –

+0

@AlexeiLevenkov 네, List를 다시 사용하고 List.Clear()도 사용했습니다 . 목록에 추가하는 것만으로 때때로 메모리를 할당하는 것 같습니다. 그 가치에 접근하는 것은 그렇지 않습니다. 목록 크기가 전송할 이미지의 크기보다 커질 때까지 할당됩니다. 문제는 내 이미지 크기가 항상 크기가 변하는 것입니다. – Programmer

+0

때로는 이미지 크기가 올라가고 때로는 아래로 내려 가서 잠시 동안'List' 할당이 발생합니다. 그것은 비록 어떤 시점에서 멈추지 만 성능 차이는 할당 메모리를 중지 한 후에도 항상 존재합니다. 나는 할당 부분을 멈추기 위해'List' 크기를 생성시에 지정할 수 있다는 것을 알고 있습니다.하지만 시간을 정해야한다면'Array'를 사용하지 않을까요? 또한,'Array' 대'List' 성능 차이를 보여주는 답변에서 링크 된 Unity 블로그를 살펴보십시오. – Programmer

2

배열과 기능의 중복에를하고 그 사실을 나열 배열을 래핑하여 구현 된 목록은 거의 항상 배열이 더 빠를 것으로 기대한다는 것을 의미합니다. 즉, 배열에 직접 액세스하면 일부 컴파일러 및 지터 최적화를 허용 할 수 있다는 것을 고려하기 전에입니다.

그렇다면, 뭔가 준비된 목록을 만들고 배열은하지 않으면 더 많은 일이 생겼습니다. 그렇게하는 것이 목록의 코드만큼 효율적이지 않은 경우에는 작업 속도를 느리게 할 수 있습니다. 완벽하게 수행 된 경우에도 예를 들어 지터가 경계 검사를 건너 뛸 수 있도록하는 코드를 가질 수 없습니다 (예를 들어 어레이의 끝에 약간의 공간을 남겨두기 때문에). 이는 실제 성능이 지터가 할 수있는 벤치 마크만큼 좋지 않음을 의미합니다 그).

사전에 관해서는 배열과 마찬가지로 해시 기반 O (1) 조회를 제공하지 않습니다.

정말 성능면에서 목록의 코드 (소스를 사용할 수 있음)를 연구하고자하는 목록에서 배열로 전환하려면 비용이 어디에 있는지 파악한 다음 해당 비용이 주어진 용도에 어떻게 영향을 미치는지 고려하십시오. 그것은 전환이 얻거나, 잃고, 깨지거나, 단지 시간 낭비가 될 것입니다. 나는 내가 완전히 기입하지 어레이에 내장 대신 는 최대 값이 있고, 크기를 추적하는 카운터 INT를 사용하여 사용하는 경우

관련 문제