C#을 위한 루프 및속 테스트...정확히 동일한 루프를 빠르게 두 번째 시간까요?

StackOverflow https://stackoverflow.com/questions/303343

문제

public Int64 ReturnDifferenceA()
{
  User[] arrayList;
  Int64 firstTicks;
  IList<User> userList;
  Int64 secondTicks;
  System.Diagnostics.Stopwatch watch;

  userList = Enumerable
              .Range(0, 1000)
              .Select(currentItem => new User()).ToList();

  arrayList = userList.ToArray();

  watch = new Stopwatch();
  watch.Start();

  for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
  {
     DoThings(arrayList[loopCounter]);
  }

  watch.Stop();
  firstTicks = watch.ElapsedTicks;

  watch.Reset();
  watch.Start();
  for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
  {
     DoThings(arrayList[loopCounter]);
  }
  watch.Stop();
  secondTicks = watch.ElapsedTicks;

  return firstTicks - secondTicks;
}

당신이 볼 수 있듯이,이것은 정말 간단합니다.목록을 작성,사용자의 힘을 배열을 시작 시계,반복 목록을 통해하고 전화하는 방법,시계를 중지합니다.반복합니다.완료 반환하여 차이를 처음부터 실행하고 두 번째입니다.

지금 나는 전화로 이러한:

differenceList = Enumerable
                 .Range(0, 50)
                 .Select(currentItem => ReturnDifferenceA()).ToList();
average = differenceList.Average();

differenceListA = Enumerable
                  .Range(0, 50)
                  .Select(currentItem => ReturnDifferenceA()).ToList();
averageA = differenceListA.Average();

differenceListB = Enumerable
                  .Range(0, 50)
                  .Select(currentItem => ReturnDifferenceA()).ToList();
averageB = differenceListB.Average();

이제 재미있는 부분에는 모든 평균은 긍정적인에 의해 상대적으로 큰 금액에 이르기까지,150kb 입을 300k 틱.

내가 무엇을 얻을하지 않는 나을 거 같은 목록과 같은 방법으로,동일한 방법 그리고 아직 이러한 차이가 있습니다.은 거기에 몇 가지 종류의 캐싱까요?

또 다른 흥미로운 것은 경우 목록을 반복하기 전에 처음 시계를 중지 섹션에서,평균 약 5k 니다.

도움이 되었습니까?

해결책

그건 그렇고, 배열에서 ienumerable.count ()를 사용하는 것은 배열보다 수백 배나 느립니다.

다른 팁

많은 캐싱 및 성능 최적화를 수행하는 런타임 환경으로 높은 수준의 언어로 실행하고 있습니다. 이것은 일반적입니다. 때로는 가상 머신 워밍업 또는 서버 워밍업 (제작 응용 프로그램 인 경우)이라고합니다.

무언가가 반복적으로 수행 될 경우, 처음에는 처음으로 측정 된 런타임이 더 크고 나머지는 더 적은 양으로 레벨을 내려야합니다.

Matlab 코드 로이 작업을 수행하고 처음 벤치 마크 루프를 실행하면 5 초가 걸리고 이후 시간은 5 초가 걸린다는 것을 알 수 있습니다. 그것은 어떤 형태의 컴파일이 필요한 해석 된 언어이기 때문에 큰 차이는 있지만 실제로는 대다수가 생산 응용 프로그램에서 두 번째 시간이되기 때문에 성능에 영향을 미치지 않습니다.

Dothings ()가 처음 호출 될 때까지 Dothings ()가 기본 코드에 통합되지 않을 가능성이 상당합니다.

Java 플랫폼과 마찬가지로 .NET은 JIT 환경이기 때문입니다. 모든 높은 레벨 .NET 코드는 Microsoft의 중간 언어 바이트 코드로 컴파일됩니다.

프로그램을 실행하려면이 바이트 코드는 기본 기계 코드로 컴파일/번역되어야합니다. 그러나 컴파일 된 .NET 프로그래밍 된 파일은 기본 기계 코드가 아니라 중간 가상 머신 바이트 코드에 저장됩니다.

첫 번째 실행은 JIT 컴파일이므로 추가 시간이 걸렸습니다. 후속 실행은 더 이상 JIT 컴파일 될 필요가 없지만 기본 코드는 JIT 캐시에서 그려져 있으므로 더 빠릅니다.

후속 실행을 종료하지 않고 신청서를 유지 했습니까? 그런 다음 두 번째 이유는 VM 때문입니다. (vm : 1 = 가상 머신; vm : 2 = 가상 메모리). 모든 최신 일반화 된 운영 체제는 실제 메모리의 맵인 가상 메모리에서 프로세스를 실행하여 운영 체제가 시스템 리소스 사용을 관리하고 최적화 할 수 있습니다. 덜 중고 프로세스는 종종 디스크 캐시로 휩쓸려 다른 프로세스가 최적의 리소스를 사용할 수 있도록합니다.

귀하의 프로세스는 처음으로 가상 메모리에 있지 않았으므로 메모리에 휩쓸리는 오버 헤드를 겪어야합니다. 그 후, 귀하의 프로세스는 가장 최근에 사용 된 최고 목록 중 하나 (일명 최근에 가장 적은 최소한 목록의 하단) 중 하나 였으므로 아직 디스크 캐시로 휩쓸지 않았습니다.

또한 OS는 필요에 따라 프로세스에 대한 리소스를 제공합니다. 따라서 첫 번째 라운드의 경우, 귀하의 과정은 OS로 봉투 경합을 밀어내어 자원 경계를 확장하는 고통을 겪어야했습니다.

가상 머신을 사용하면 .NET 및 Java가 대부분의 프로그래밍 기능을 기계 독립 계층으로 추상화하여 기계 의존 소프트웨어 엔지니어가 처리 할 수있는 작은 혼란을 남길 수 있습니다. Microsoft Windows는 오히려 통합 된 X86 Descendant 하드웨어에서 실행되지만, .NET 프로그래머와 사용자에게 일관된보기를 제공하기 위해 추상화 된 가상 머신을 보증하기 위해 다양한 OS 버전 및 CPU 모델에는 충분한 차이가 있습니다.

당신은 당신이 그것을 3 번하지 않는다고 말하고, 두 번째와 세 번째는 비교적 가깝습니다. 루프를 통해 처음으로 일이 느리게 나온 것 같습니다.

내가 의심되는 함수를 호출은 단지에는 시간까지 첫 번째 실행됩니다.당신이 시도할 수 있습니다 그것을 실행하면,그때 그것을 멈추고 다시 실행하십시오.코드 없이 변경,Just-In-Time 컴파일 이전에서 실행해야 합 확인,및 나머지 최적화를 볼 수 있는 캐시 효력에서 작동합니다.

VM 또는 기계, 캐싱, JIT 최적화, 잠시 동안 워밍업하는 문제를 제외하십시오. 컴퓨터는 또 무엇을하고 있습니까? 3E42 시스템 서비스 및 작업 트레이가 일부 CPU를 잡고 있습니까? Steam Client가 업데이트를 확인하기로 결정했을 수도 있고, 즉, 심하게 중요한 일을해야 했습니까, 아니면 바이러스 백신 프로그램이 방해가 되었습니까?

귀하의 테스트는 상자에서 실행되는 다른 모든 소프트웨어에서 분리 할 수있는 정도만큼 유용합니다. 실행을 측정하기 전에 가능한 모든 소프트웨어를 끄십시오.

그러나 나는 무엇을 알고 있습니까? - 측정 방법은 .NET (또는 무엇이든) 런타임에 의해 관리되며 런타임 '가상 사이클'만을 설명 할 수 있습니다.

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