여기에서 찾을 수있는 가장 가까운 질문은 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 밀리 초마다 수신됩니다.
메모리가 그다지 염려가 없다면 더 큰 용량의 사전을 초기화하고 시간을 단축시키는 포인트가 있는지 알아볼 수 있습니다. http://www.dotnetperls.com/dictionary-optimization – keyboardP
' 거기에 논리에 대해 조금 혼란 스럽네요. 당신이 지금 가지고있는 사전 2 개 대신 Dictionary를 사용할 수 있습니까? 그러면 라인 1과 2는 tempInnerObject = BusinessObjectList [i] .ObjectList [i]와 같은 것으로 병합됩니다; ... 어쩌면 거기에 또 다른 논리적 인 문제가 2 가지로 인덱스하는 데 사용되는,하지만 또한 복사 붙여 넣기 + 편집 –
@ 미케 Trusov의 유물이 될 수 있기 때문에, 나는 하나의 하나로 두 사전을 병합 할 수 없습니다 - 데이터 TCP를 통해 수신되는 것은 색인을 기반으로합니다. 그래서 위에서 언급 한 for 루프에서 비즈니스 객체의 인덱스가 필요합니다. 따라서 사전은 비즈니스 오브젝트 이름을 인덱스로 변환하는 데 사용됩니다. 다른 모든 시간에 Business Object Dictionary는 해당 이름을 사용하여 액세스됩니다. –
silverspoon