2014-02-27 2 views
0

목록에 정점을 유지하고 있는데, 정점을 아직 포함하지 않은 경우에만 정점을 목록에 추가하려고합니다. 그것이 포함되어 있지 않으면 목록에 추가 한 다음 tris라는 목록에 색인을 추가합니다. 그러나 목록에 이미 정점이 포함되어 있으면 해당 위치의 색인을 찾아야하며 그 색인을 트리스 목록에 추가하면됩니다. 여기에 내가 알아 낸 가장 빠른 방법이 있습니다. 더 빠른 방법이 있습니까?배열의 인덱스를 가지고있는 것보다 더 빨리 찾을 수 있습니까?

Hashtable vertIndexes; 
List<Vector3> verts; 
List<int> tris; 

foreach (var vert in vertsOutput) 
{ 
    Vector3 p = point + vert; 
    if(!vertIndexes.Contains(p)) 
    { 
     vertIndexes.Add(p, verts.Count); 
     tris.Add(verts.Count); 
     verts.Add(p); 
    } 
    else 
    { 
     tris.Add((int)vertIndexes[p]); 
    } 
} 
+0

색인으로 'for'를 사용하는 것이'foreach'보다 빠르다는 것을 읽었습니다. 그것 이외에 여러분은'Dictionary '을 사용할 수 있는데, 이것은 정점 O (1)을 찾게합니다. –

+1

@ThorstenDittmar - Hashtable에는 O (1)도 있습니다.이 태그는 사전 <>으로 일반화되어 있지 않으므로 복싱/언 박싱에 비용을 지불하고 있습니다. 또한 해시 테이블 (또는 사전 <>)은 실제 채우기 1/3보다 큰 용량을 가지도록 할당해야합니다. 개인적인 경험에서 가장 좋습니다. –

+0

나는 @ThorstenDittmar에 동의하지만 사전이 아니라'HashSet ' –

답변

3

현재 항목 당 2 개의 해시 테이블 작업을 수행하고 있습니다. 다음 중 하나를 저장할 수 있습니다 :

Dictionary<Vector3, int> vertIndexes; 
... 

int index; 
if(vertIndexes.TryGetValue(p, out index)) 
//present at given index 
else 
//not present 

TryGetValue 동시에 존재 여부를 테스트하고 저장된 값을 반환합니다.

사용자 지정 해시 테이블을 사용하면 더 빨라질 수 있습니다. Dictionary에는 일반적으로 필요한 오버 헤드가 있으며 필요하지 않습니다. 예를 들어, 모듈러스 연산자는 놀랍게도 비싸고 좋은 해시 코드에서는 불필요합니다. 그러나이 답변의 범위를 벗어납니다.

+0

나는 이것을 사용하여 많은 성능 향상을 보지 못했고, 나중에 사용자 정의 해시 테이블을 시험해 보았습니다. 어쩌면 다른 것을 느리게하는 것이 있을까요? – Shredder2500

+0

아주 훌륭하게 가능합니다. 코드를 프로파일 링하거나 디버거를 10 번 일시 중지하여 가장 자주 멈추는 위치를 확인하십시오.; 어쩌면 당신은 자주 당신이 딕트에 추가하는 경우를 취하고 있습니다. 사용자 정의 해시 테이블을 사용하면 모든 작업을 하나의 조회로 결합한 사용자 정의 작업을 작성할 수 있습니다. 올바른 버켓 인덱스를'hashCode & (length-1)'로 신속하게 계산할 수 있도록 두 개의 2의 제곱 크기를 사용하십시오. 모듈러스보다 훨씬 빠릅니다. – usr

1

많은 종류의 컨테이너가 있으며 성능, 리소스 및 활용 특성이 모두 다릅니다.

목록이 검색을위한 가장 빠른 컨테이너가 아닙니다. 사전이나 Hashset이 더 좋을 수도 있습니다. 하지만 사용 방법에 따라 다릅니다.

키로 정점을 검색해야하는 경우 사전을 사용하십시오. 꼭짓점 자체가 키이면 해시 테이블을 사용하십시오. 그런 다음 인덱스에 대해 별도의 해시 테이블이 필요하지 않습니다.

실제로 카운트해야합니까? 그렇지 않다면 정점에 해시 테이블을 사용하십시오. 개수가 필요하면 정점에 키가있는 사전을 사용하십시오. Dictionary<Vertex3,int>

+0

내가 결국 필요로하는 것은 벡터 배열을 가진 두 개의 배열이고 하나는 벡터를 가리키는 인덱스를 가진 – Shredder2500

+0

삼각형을 만드는 배열이다 @ Shredder2500 - 나는 3D 렌더링에 대해 많이 알지 못한다. 다른 배열에 인덱스 배열? 그것은 서수인가 실제 참조입니까? 실제 참조 인 경우 실제 꼭지점 목록과 다른 점은 무엇입니까? –

+0

유니티는 삼각형 배열을 통과 할 것이고 그 삼각형리스트의 인덱스를 얻고 vert 배열에서 vert를 찾을 것입니다.verts는 어떤 순서로도 될 수 있지만 트라이스트 순서는 삼각형을 렌더링하는 방법을 알려줍니다 – Shredder2500

관련 문제