2013-01-21 3 views
4

여기에서 찾을 수있는 가장 가까운 질문은 C# Dictionary Loop Enhancment이지만 그 점이 도움이되지 못했습니다.사전 값 읽기 및 배정 실적

다음 코드는 내 프로젝트에서 가지고있는 코드입니다. 데이터 구조, 그래서 그냥 내가 여기의 간단한 양식을 만들었습니다 설명을 위해 매우 복잡하다 : 1 ~ 5에서 표시

public class BusinessObject 
{ 
    public Dictionary <int, InnerObject> objList = new Dictionary <int, InnerObject>(); 
    public string Name {set;get;} 

    public Dictionary <int, InnerObject> ObjectList // <index, InnerObject> 
    { 
     get 
     { 
      return ojbList; 
     } 
    } 
} 

... 
... 
... 
// <Name of the BusinessObject, BusinessObject> 
public Dictionary <string, BusinessObject> BusinessObjectList; 
// names of all the business objects has an index in this dictionary 
public Dictionary <int, string> BusinessObjectListIndexes 

... 
... 
... 

//On receiving the values over TCP, following loop executes. This loop will iterate over about a million values depending on the type of that value: 

int currentIndex = 0; 
string name = ""; 
InnerObject tempInnerObject; 

for(int i = 0; i < valueCountReceivedOverTCP; i++) // valueCountReceivedOverTCP can be up to 1 million 
{ 
/* 1. */ name = BusinessObjectListIndexes[i];          
/* 2. */ tempInnerObject = BusinessObjectList[name].ObjectList[i];     
/* 3. */ tempInnerObject.ReceivedTime = valuesReceivedOverTCP->Time;    

    switch(valuesReceivedOverTCP->Type) 
    { 
     case TCPType.INT: 
      bytearray[0] = valuesReceivedOverTCP->Values[++currentIndex]; 
         bytearray[1] = valuesReceivedOverTCP->Values[++currentIndex]; 
         bytearray[2] = valuesReceivedOverTCP->Values[++currentIndex]; 
         bytearray[3] = valuesReceivedOverTCP->Values[++currentIndex]; 

         tempint = BitConverter.ToInt32(bytearray, 0); 
/* 4. */   tempInnerObject.Value = tempint;      
     break; 

     case TCPType.DOUBLE:             
         bytearray[0] = valuesReceivedOverTCP->Values[currentIndex+1]; 
         bytearray[1] = valuesReceivedOverTCP->Values[currentIndex+2]; 

         bytearray[2] = valuesReceivedOverTCP->Values[currentIndex+3]; 
         bytearray[3] = valuesReceivedOverTCP->Values[currentIndex+4]; 

         bytearray[4] = valuesReceivedOverTCP->Values[currentIndex+5]; 
         bytearray[5] = valuesReceivedOverTCP->Values[currentIndex+6]; 

         bytearray[6] = valuesReceivedOverTCP->Values[currentIndex+7]; 
         bytearray[7] = valuesReceivedOverTCP->Values[currentIndex+8]; 

         currentIndex += 8;       
         tempdouble = BitConverter.ToDouble(bytearray, 0); 
/* 5. */    tempInnerObject.Value = tempdouble; 


     break; 
    } 

} 

라인은 문제를 가진 사람입니다. 위의 내용은 ANTS Performance Profiler를 사용하여 시간이 걸리는 것을 발견했습니다. 그들은 모두 상당한 시간이 걸립니다. 두 번째 줄은 주요 시간 낭비입니다. for 루프는 약 700,000 값에 대해 약 250 밀리 초가 걸립니다. 비록 밀리 세컨드이지만 소프트웨어를 위해 받아 들일 수 없기 때문에 이것을 줄이고 싶습니다. 나는 또한 루프를 루프를 이용하여 System.Threading.Tasks.Parallel.Invoke()을 사용하여 4 개의 병렬 루프로 분할하려고했지만 성공하지 못했습니다.

제 질문은 -이 논리 또는 코드에 명백하게 잘못된 것이 있습니까? 이 코드가 더 빠르게 실행되도록하는 솔루션은 무엇이 될 수 있습니다. .NET Dictionary의 성능 제한을 초과하면 모든 것을 다르게 구현해야한다는 것을 이해합니다. 이 코드가 더 빨리 실행되도록하기 위해 내 설계/구현을 변경하는 것을 의미하는 경우라도 제안을 공개합니다.

편집 : 매우 첫 번째 TCP 메시지로서이 값들의 순서와 총 개수를 얻습니다. 주문을 키로 저장하고 비즈니스 오브젝트 이름을 값으로 BusinessObjectListIndexes에 저장합니다. 첫 번째 메시지 이후로 나는 BusinessObject 이름을 얻지 못했습니다. 첫 번째 메시지에서 지정한 순서대로 값만 수신됩니다. 그런 다음 모든 메시지에서받은 값으로 BusinessObjectList를 업데이트합니다. 이것이 내가 개선 된 성능을 필요로하는 곳이다. TCP 메시지는 업데이트 된 값을 제공하는 250 밀리 초마다 수신됩니다.

+0

메모리가 그다지 염려가 없다면 더 큰 용량의 사전을 초기화하고 시간을 단축시키는 포인트가 있는지 알아볼 수 있습니다. http://www.dotnetperls.com/dictionary-optimization – keyboardP

+0

' 거기에 논리에 대해 조금 혼란 스럽네요. 당신이 지금 가지고있는 사전 2 개 대신 Dictionary 를 사용할 수 있습니까? 그러면 라인 1과 2는 tempInnerObject = BusinessObjectList [i] .ObjectList [i]와 같은 것으로 병합됩니다; ... 어쩌면 거기에 또 다른 논리적 인 문제가 2 가지로 인덱스하는 데 사용되는,하지만 또한 복사 붙여 넣기 + 편집 –

+0

@ 미케 Trusov의 유물이 될 수 있기 때문에, 나는 하나의 하나로 두 사전을 병합 할 수 없습니다 - 데이터 TCP를 통해 수신되는 것은 색인을 기반으로합니다. 그래서 위에서 언급 한 for 루프에서 비즈니스 객체의 인덱스가 필요합니다. 따라서 사전 은 비즈니스 오브젝트 이름을 인덱스로 변환하는 데 사용됩니다. 다른 모든 시간에 Business Object Dictionary는 해당 이름을 사용하여 액세스됩니다. – silverspoon

답변

0

BusinessObjectListIndexesObjectList 속성의 키만 인덱스로 사용하는 것으로 보입니다. Dictionary 클래스는 이것을 알지 못하지만 여전히 키/색인을 검색해야합니다.

Array으로 변경 한 경우 크기를 알지 못했거나 사용하기가 더 쉽다는 것을 알고 있다면 더 나은 성능을 얻을 수있을 것으로 생각됩니다. (평균?) 크기에 따라 다른 유형이 더 적합 할 수도 있지만 사전이 여기에 올바른 선택이 아닌 것 같습니다.