문제

나는 항상되는 성분을 추가하는 배열에 일어나는 다음과 같다:

빈의 복사본을 배열+1element 가 만들어지고 다음 데이터 원래의 배열로 복사 그런 다음 새로운 데이터에 대한 새로운 요소입 그런 다음 로드

이것이 진실한 경우,그 배열을 사용하는 시나리오를 많이 필요로하는 요소의 활동은 콘트라 표시된 때문에 메모리고 CPU 사용률,정확합니까?

이 경우에는 안됩니다,당신은 피하려고 배열을 사용하여 가능한 한 많은 경우에 추가할 것이 많은 요소가?을 사용해야 하는 iStringMap 까요?그렇다면,무엇이 필요한 경우 두 개 이상의 치수를 추가할 필요가 많은 요소의 추가 사항입니다.당신은 단지 성능 저하 또는 다른 뭔가가 있는 사용되어야 하는가?

도움이 되었습니까?

해결책

보 일반 List<T> 을 위한 보충으로 배열입니다.그들은 지원 대부분의 것들을 배열 do 포함하여 할당하여 초기의 저장소 크기 원하는 경우.

다른 팁

이에 따라 당신이 무엇을 의미하여"추가."

는 경우에 당신을 의미한다:

T[] array;
int i;
T value;
...
if (i >= 0 && i <= array.Length)
    array[i] = value;

그런 다음,아,이것을 만들지 않으로 새로운 배열,고 사는 가장 빠른 방법을 변경하는 모든 종류의 명령합니다.NET.

는 경우,그러나,당신이 무언가를 사용하여 다음과 같 ArrayList,목록,수집,etc.다음 호출하면"추가"방법 새로 만들 배-그러나 그들은 그것에 대해 스마트에서,그들은 단지 크기를 조정하여 1 요소,그들은 성장을 기하학적으로,그래서 만약 당신이 추가하는 값이 많이만 모든면에서는 동안 그것을 할당해야 새로운 배열입니다.그럼에도 사용할 수 있습니"능력"속성을 강제로 성장하기 전에 손을 어떻게 알고 있는 경우에,많은 요소를 추가하(list.Capacity += numberOfAddedElements)

일반적으로,난을 피하기 위해 선호하는 배열을 사용합니다.사 목록<T>.그것을 사용하여 동적으로 크기 배열,내부적으로 그가 충분히 빠른 대부분의 사용합니다.를 사용하는 경우 다-dimentional 배열을 사용하여 목록<List<List<T>>>는 경우가 있습니다.그것은 훨씬 더 메모리의 관점에서,그리고 훨씬 간단하는 항목을 추가.

에 있다면 0.1%의 사용을 필요로 하는 극단적인 속도로 확인 그것은 당신의 목록에 액세스는 정말 하기 전에 문제를 최적화하려고 노력하는니다.

려고하는 경우 추가/제거하는 요소를 많이,그냥 목록을 사용합니다.는 경우 그것은 다차원,당신은 항상 사용할 수 있 목록<List<int>>또는 무언가이다.

반면에,목록은 더 적은 보다 효율적인 배우는 대부분 하고 있는 기 때문에,목록 배열에 모두 한 장소에서 당신의 CPU 캐시물 목록에 흩어져 있습니다.

사용하려는 경우에는 배열에 대한 효율적인 읽기만 할거야""추가 요소,자주 당신은이 두 가지 옵션:

1)생성하는 그것을 목록으로(또는 목록의 목록)및 다음 사용하 ToArray()으로 효율적인 배열 구조입니다.

2)배보다 크게 당신이 필요,그 후로 사전에 할당된 세포입니다.는 경우에 당신을 필요로도 더 많은 요소들보다 당신은 사전에 할당할 수 있습을 재배열될 때 그것을 채우기,두 배로 크기를 각각의 시간입니다.이 O(로그 n)크기 조정 성능을 대신 O(n)같은 것으로 할당-once-per-추가 배열입니다.참고로 이것은 매우 많은 방법 StringBuilder 작동을 제공,당신은 빠른 방법을 지속적으로 추가하기에는 문자열을 사용합니다.

을 때의 사용을 포기하는 배열

  1. 먼저, 할 때 의미의 배열 일치의 목적으로 -필요에 동적으로 성장 컬렉션?트는 허용되지 않 중복?는 컬렉션은 변경이 불가능한 상태로 남아 있는지?을 피하기 어레이는 모든 경우.는 99%의 경우입니다.그냥 알리는 명백한 기본 지점입니다.

  2. 둘째, 할 때 코딩을 위해 절대적 성능 criticalness -의 약 95%의 경우입니다. 배열이 더 나은 수행 는 소폭, 특히 반복.그것은 거의 항상 적이 문제입니다.

  3. 강제에 의하여 인수 params 키워드 -난 그냥 바랬다 params 허용된 모든 IEnumerable<T> 또는 더 좋은 언어를 구축 자신을 나타내 순서 (그리고 프레임 타입)으로 구성되어 있습니다.

  4. 할 때 쓰 레거시 코드,또는 다루는 interop

에서 짧은,그것의 매우 드문 것이 실제로 필요한 훌륭한 기능들을 가지고 있습니다.나는 것으로 추가하는 이유는 하나의 피하는 것입니까?

  1. 가장 큰 이유는 피하기 어레이 imo 은 개념적입니다.배열은 가을 구현하고 멀리에서 추출한 것입니다.배를 전달하 more 수행하는 방법는 무엇입 완료 이는 성령의 높은 수준 언어입니다.놀라운 일이 아니다,고려하고 배 가까이 있는 금속,그들은 바로 나의 특별한 형식(비록 내부적으로 배열은 클래스).지 않을 교육,그러나 배열이 정말로 번역을 의미 아주 아주 드물게 필요합니다.가장 유용하고 빈번한 의미의 컬렉션의 모든 항목을 설정하고,별개의 항목,키 값을 지도 등의 조합을 사용하여 추가 가능한,readonly,변경할 수 없는,주문을 존중하는 변형이 있습니다.이것에 대해 생각할 수 있습는 추가 가능한 컬렉션,또는 읽기 전용 컬렉션으로 미리 정의된 항목 없이 추가 수정하지만,어떻게 자신의 논리처럼"내가 원하는 동적으로 추가 가능한 컬렉션을 하지만 고정된 숫자들과 그들의 수정할 수 있도"?매우 희귀 난 말하는 것입니다.

  2. 편도록 설계되었는 동안전-제네릭 시대에 그것을 흉내내 제네릭함으로 많은 실행 시간 해킹과 보여줍니다 기다.의 일부를 잡는 내가 발견:

    1. 깨 공분산.

      string[] strings = ...
      object[] objects = strings;
      objects[0] = 1; //compiles, but gives a runtime exception.
      
    2. 배열을 줄 수 있을 참조하여 구!.는 다른 곳과는 달리입니다.샘플:

      struct Value { public int mutable; }
      
      var array = new[] { new Value() };  
      array[0].mutable = 1; //<-- compiles !
      //a List<Value>[0].mutable = 1; doesnt compile since editing a copy makes no sense
      print array[0].mutable // 1, expected or unexpected? confusing surely
      
    3. 실행 시간을 구현 방법 ICollection<T>.Contains 할 수 있는 다른 구조체에 대해서는 클래스.그것은 큰 문제가되지 않습니다,하지만 경우에 당신은 당신 재정의 non 일반 Equals 에 대해 제대로 참조 형식을 기대하고 일반적인 컬렉션을 찾을 대 일반 Equals, 을 얻을 것이 잘못된 결과입니다.

      public class Class : IEquatable<Class>
      {
          public bool Equals(Class other)
          {
              Console.WriteLine("generic");
              return true;
          }
          public override bool Equals(object obj)
          {
              Console.WriteLine("non generic");
              return true;
          } 
      }
      
      public struct Struct : IEquatable<Struct>
      {
          public bool Equals(Struct other)
          {
              Console.WriteLine("generic");
              return true;
          }
          public override bool Equals(object obj)
          {
              Console.WriteLine("non generic");
              return true;
          } 
      }
      
      class[].Contains(test); //prints "non generic"
      struct[].Contains(test); //prints "generic"
      
    4. Length 속성 [] 인덱에 T[] 을 것 일반 속성을 통해 액세스할 수 있습니다 반사(해야 하는 일부를 포함)에러 표현이 나무를 침 정확히 동일한 코드를 컴파일러는 않습니다.가 ArrayLengthArrayIndex 방법는 따로 있습니다.하나는 이러한 여기에 문제.또 다른 예를 들어:

      Expression<Func<string>> e = () => new[] { "a" }[0];
      //e.Body.NodeType == ExpressionType.ArrayIndex
      
      Expression<Func<string>> e = () => new List<string>() { "a" }[0];
      //e.Body.NodeType == ExpressionType.Call;
      

는 방법의 사용을 포기하는 배열

가장 일반적으로 사용되는 대체 List<T> 는 청소기 API 를 사용합니다.하지만 그것은 동적으로 성장하는 구조를 할 수 있음을 의미하는 추가 List<T> 에 삽입은 어디에서나 모든 수용량.대체할 수 없는 정확한 행동이의 배열을,하지만 사람들이 주로 배열을 사용하여 읽기 전용으로 컬렉션할 수 없습니다 아무것도 추가 끝나가고 있습니다.대체입 ReadOnlyCollection<T>.나는 이 확장은 방법:

public ReadOnlyCollection<T> ToReadOnlyCollection<T>(IEnumerable<T> source)
{
    return source.ToList().AsReadOnly();
}

때 배열의 크기를 조정,새로운 배열해야 할당된 내용을 복사됩니다.는 경우에 당신은 단지 내용을 수정할 수의 배열을,그것은 단지 메모리 할당합니다.

그래서,당신은 배열을 사용하지 않는 경우 알 배열의 크기,또는 크기 변경될 수 있습니다.그러나 만약 당신이 고정 길이 배열을,그들이기 쉬운 방법으로 검색하는 요소에 의해 인덱스입니다.

ArrayList 고 목록 성장을 배열해 하나 이상의 필요할 때(나는 그것에 의해 두배로 하는 크기,그러나 나는 확인되지 않은 소스).그들은 일반적으로 최고의 선택할 때는 건물의 동적으로 크기 배열입니다.

할 때 벤치마크를 나타내는 배열의 크기를 조정가 심각하게 둔화되는 응용 프로그램(을 기억하-조 최적화는 모든 악의 뿌리)평가할 수 있습 쓰기 사용자 정의 배열 등과정 크기를 조정하는 동작입니다.

일반적으로 사용해야 하는 경우에는 최고의 인덱싱 조회 성능의 최고 목록을 작성하기 위해 먼저 다음 차례로 배열에 따라서 지불하는 작은 벌금에 처음 하지만 피하는 모든 후입니다.문제일 경우는 것은 당신이 지속적으로 추가하는 새로운 데이터를 데이터 수 있습니다 다음 사용하려 ArrayList 또는 목록의 편의를 위해 그러나 유지 하는 마음에 그들은 단지 특별한 케이스 배열입니다.때 그들은"grow"그들은 할당 완전히 새로운 배열 및 사본에 모든 것 그것이는 매우 느립니다.

ArrayList 은 단지 배열하는 성장 필요로 할 때.추가 청산 O(1),단지 주의해야하는지 확인 크기 조정이 일어나지 않을 것에습니다.삽입 O(n)모든 항목은 오른쪽으로 이동해야 합니다.Remove O(n)모든 항목은 오른쪽으로 이동해야 합니다.

하는 것도 중요하지 하는 마음에 목록하지 않는 링크 목록입니다.그것은 단지 입력 ArrayList.목록 문서 가 참고 수행하는 더 나은 대부분의 경우에만 말하지 않는다는 이유.

최고의 것을 하는 것을 선택하는 데이터 구조는 적절한 문제입니다.이 한 일을 많이하는 경우가 있으므로 검색 시스템입니다.컬렉션이 있습니다.일반 네임스페이스가 있습니다.

이 특정한 경우를 말하는 경우에 오를 수 있는 좋은 핵심 가치 사전 것이 당신의 최선의 방법입니다.그것은 삽입하고 제거하는 방식 O(1).그러나 심지어 사전에 당신은하지 않도록 주의해 주십시오 그것은 크기를 조정의 내부 array(O(n)동작).그것을 제공하기 위해 최선을 그들을 많이의 방을 지정하여 더 큰--다음을 기대를 사용하여 초기 용량에서 생성자입니다.

-릭

표준 배열해야으로 정의 길이를 보유 메모리 모두 필요로 하는 연속된다.에 항목을 추가하면 배열 안에 넣어의 블록의 이미 reserved 메모리입니다.

배열에 대한 좋은 몇 가지 기록하고 많은 읽고,특히 이들의 반복적인 자연 무엇을 위해,사용 중 다른 많은 데이터 구조입니다.

당신이 올바른지 배열을 위해 중대하 모니다.그러나 수정 크기의 배열은 비용이 많이 듭니다.

당신이 사용해야 하는 컨테이너을 지원하는 증가 크기 조정 시나리오에는 수정할 배열의 크기.당신이 사용할 수 있는 배열을 설정할 수 있는 초기 크기,그리고 당신은 수 있는 지속적으로 확인에 크기와 수용량 그리고 다음을 증가시키는 용량으로 큰 덩어리를 제한 번호의 크기를 조정합니다.

또는 당신은 단지 사용 링크 목록입니다.그러나 그때 보이는 느린...

이 포럼 게시물을 수도 있습니다 일부 사용에 대한 효율성의 다양한 배열 형식은:C#배열-다차원 문자 대

는 경우 나가 생각하는 것에 항목을 추가한 컬렉션이 많이 일생동안,보다 나는 목록을 사용합니다.으면 내가 무엇인지 확실히 알 크기의 컬렉션을 때 선언,다음 사용 훌륭한 기능들을 가지고 있습니다.

다른 시간 내가 일반적으로 배열을 사용하여 위 목록을 때 저는 필요 컬렉션을 반환로는 객체의 속성-나는 원하지 않는 발신자 추가하는 항목 수집 목록을 통한 추가 방법,하지만 그 대신 그들을 원하는 항목을 추가 수집을 통해 내체의 인터페이스입니다.이 경우에는,내가 내 목록과 통화 ToArray 와 배열을 반환.

는 경우가 많은 일을 할 수의 추가, 하는 것은 랜덤 액세스(예: myArray[i]).고려할 수 있었을 사용하여 연결 리스트(LinkedList<T>)기 때문에,그것은 없을 것입니다"grow"아 List<T> 구현합니다.하지만,당신이 정말로 접근 항목에 LinkedList<T> 구현을 사용하여 IEnumerable<T> 인터페이스입니다.

가장 좋은 방법은 당신이 할 수 있는 한 많은 양의 메모리를 할당하는 것이 필요 upfront 가능한 경우.이 .NET 에서는 추가로 호출하여 얻을 메모리에 힙.실패하는 그 다음 그것을 할당하에서 다섯 덩어리 또는 어떤 수은 의미에 대한 응용 프로그램입니다.

이것은 규칙에 적용할 수 있는 정말 아무것도.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top