2011-01-18 1 views
0

, 페이지는 정의 이 배열의 누구든지 가장 안쪽에있는 부유물 크기를 늘리는 방법을 말할 수 있습니까? 실패 1효율적으로 사전 내에서 사용 권투없는 값의 배열, 크기를 조정하는 방법 <문자열을 떠 []> 아래의 코드에서

var tt = currentContainer.Pages[dateTime]; 
Array.Resize<float>(ref tt, currentContainer.Pages.Count + 1); 

나는 다음 코드를 시도하고 범위 예외에서 인덱스를 얻을

SortedDictionary<DateTime, float[]> Pages = new SortedDictionary<DateTime,float[]>(); 
    float[] xx = new float[1]; 
    xx[0] = 1; 
    DateTime tempTime = DateTime.UtcNow; 
    Pages.Add(tempTime, xx); 
    var tt = Pages[tempTime]; 
    Array.Resize<float>(ref tt, Pages.Count + 1); 
    Pages[tempTime][1] = 2; 

실패 2

다음은 컴파일 타임 오류를 (제공 속성, 인덱스 또는 동적 멤버를 참조 값으로 사용할 수 없음)

SortedDictionary<DateTime, float[]> Pages = new SortedDictionary<DateTime,float[]>(); 
    float[] xx = new float[1]; 
    xx[0] = 1; 
    DateTime tempTime = DateTime.UtcNow; 
    Pages.Add(tempTime, xx); 
    var tt = Pages[tempTime]; 
    // The line below is different from Fail 1 above ... compile time error 
    Array.Resize<float>(ref Pages[tempTime], Pages.Count + 1); 
    Pages[tempTime][1] = 2; 

질문

이 배열의 크기를 조정하는 가장 성능이 좋은 대답은 무엇입니까?

최종 크기가 100-200 floats 또는 700-900 floats가 될 가능성이 있다면 답변이 변경됩니까?

할당 크기를 +1에서 +128 사이로 변경하면 어떻게됩니까? .. 아니면 더 커? 사용 List<T>

+1

그냥'SortedDictionary 사용하지 않는 이유가 <날짜 시간이 목록 >'대신? 크기를 조정할 필요는 없습니다. 목록에서 Add()를 호출하기 만하면됩니다. ??? –

+0

목록 또는 링크 된 목록이 수레의 순서를 보장합니까? 그것은 저에게 아주 중요합니다. – LamonteCristo

+0

목록 내 플로트 값 유형에 대한 boxing/unboxing이 많이 발생합니다. 아마도 최선의 선택이 아닐 것입니다. – LamonteCristo

답변

7

,

예,

SortedDictionary<DateTime, List<float>> data; 

data = new SortedDictionary<DateTime, List<float>>(); 

data.Add(DateTime.Now, new List<float>() { 11.4f, 322.3f, 33.5f }); 

편집 :

방법 목록에서/설정 값을 얻기 위해?

List<float> a = new List<float>() 
{ 
    10.2f,20.3f 
}; 

float v1 = a[0]; 
float v2 = a[1]; 

Console.WriteLine("{0} {1}", v1, v2); 

a[0] = 90.40f; 
Console.WriteLine("{0} {1}", a[0],a[1]); 
+0

List 또는 Linked List는 수레의 순서를 보장합니까? 그건 나에게 매우 중요합니다. – LamonteCristo

+2

예. 주문이 유지됩니다. –

+0

+1 목록 사용. List와 LinkedList는 모두 Dictionary와 HashSet과 달리 순서를 보존합니다. 목록은 배열과 같습니다. –

1

Array.Resize (ref tt, Pages.Count + 1); 페이지 [tempTime] = tt;

+0

자주 크기 조정 작업이이 경우 스택이나 힙에 압력을가합니까? – LamonteCristo

+0

목록 은 힙/CPU와 관련하여 더 나은 작업을 수행합니다. Array를 호출하면크기를 자주 조정하십시오 (특히 샘플에서 1만큼 증가 시키면) 많은 데이터를 복사 할 때 메모리 할당과 CPU에 심각한 압력을 가할 것입니다. –

1

대신

공개 SortedDictionary < 날짜 시간의 플로트 [] "페이지 {얻는다; 세트; },

당신이 사용할 수

공공 SortedDictionary < 날짜 시간, 목록 < 플로트 >> 페이지 {얻을; 세트; },

이므로 크기를 조정할 필요가 없으며 여전히 배열로 액세스하려는 경우 List 클래스의 ToArray()를 항상 사용할 수 있습니다.

희망이 대신에 배열하는 Dictionary<DateTime, List<Float>> 사용을 고려 않습니다

+0

목록 내 플로트 값 유형에 대한 boxing/unboxing이 많이 발생합니다. 아마도 최선의 선택이 아닙니다. – LamonteCristo

+0

컬렉션과 관련하여 제네릭을 사용하면 실제 T [] 배열을 활용하여 복싱을 피할 수 있습니다. 목록 은 예를 들어 T [] 배열을 사용하여 내용을 저장합니다. http://stackoverflow.com/questions/4403055/boxing-unboxing-and-generics 물론 배열은 참조 유형이므로 힙에 저장된 (CLR의 현재 버전에서는 yada yada) . 하지만 T [] 객체가 아니기 때문에 배열의 요소는 "직접"저장할 수 있습니다. 즉, 그들은 여전히 ​​힙에 있지만 박스형이 아닌 배열의 힙에 있습니다. 배열을 갖는 것은 상자에 대한 참조를 포함합니다. – Divi

+0

+1 전체적으로이 게시물에 대한 귀하의 링크 및 의견 ... 감사합니다! – LamonteCristo

3

먼저 도움을줍니다. 코드 예제는 모두 배열 크기를 1 씩 늘리는 것과 관련되어 있으므로 최종 크기를 얻으려면 배열의 크기를 여러 번 조정해야합니다. 그렇다면 자체적으로 확장 할 수있는 컨테이너를 선택하고 그렇게 효율적으로 수행 할 수있는 컨테이너를 선택하는 것이 더 좋을 것입니다.

둘째, 모든 예제는 사전의 항목 수보다 하나 많은 배열 길이를 사용합니다. 비정상적인 관계입니다. Dictionary<DateTime, (some group of floats)>이 적절한 컨테이너라고 확신합니까?

그런데 사전에 배열의 크기를 조정하는 방법은 다음과 같습니다.

SortedDictionary<DateTime, float[]> Pages = new SortedDictionary<DateTime,float[]>(); 
DateTime date = DateTime.UtcNow; 

float[] arr = Pages[date]; 
Array.Resize<float>(ref arr, arr.Length + 1); 
Pages[date] = arr; // [] overwrites the old value, unlike Add(). 
+0

크기 조정 작업을 자주하면 스택이나 힙에 압력이 가해 지나요? – LamonteCristo

+0

힙에. 또는 더 구체적으로 가비지 수집기에 대한 추가 작업을 수행하고 있습니다. –

+0

내가보고 & 읽는 것에 따라 ArrayList, List 및이 메서드를 비교합니다. 배열에 500 개 이상의 항목이 있는지 확인하여 목록을 정당화 할 것인지 확인할 것입니다. LamonteCristo

1

다른 답변에서 제안한대로 목록을 사용합니다. Array.Resize()으로 배열을 변경할 수없는 이유는 배열을 새로운 배열에 복사하기 때문에 (Reflector 출력은 아래에 나와 있습니다) 새로운 값을 Pages[tempTime]에 다시 지정하지 않으면 배열이 꺼집니다. 운.

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
public static void Resize<T>(ref T[] array, int newSize) 
{ 
    if (newSize < 0) 
    { 
     throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
    } 
    T[] sourceArray = array; 
    if (sourceArray == null) 
    { 
     array = new T[newSize]; 
    } 
    else if (sourceArray.Length != newSize) 
    { 
     T[] destinationArray = new T[newSize]; 
     Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length); 
     array = destinationArray; 
    } 
} 
관련 문제