본문 바로가기

backup

C# Timer 성능 측정을 위한 ms이하 까지 측정 가능한 Timer

C# 성능 측정을 위한 Timer

 

 

 

 

 

연산의 성능 개선을 위해서는 정확한 성능 측정이 필요로 한데 특히 HFT와 같이 고속 연산을 하기 위해서는 1ms이 아니라 1/1000 ms도 중요하다. 하지만 일반적인 C#에서의 timer 즉 C# DateTime 객체를 써봐야 1ms 단위까지 밖에 측정을 할 수가 없기 때문에 마땅한 방법이 없다.

 

한가지 방법으로는 연산을 십만번쯤 반복하고 걸린 시간에서 십만을 나누는 것도 하나의 방법이겠지만, Win32에 있는 QueryPerfomanceFrequency와 QueryPerfomanceCounter를 사용하면 1ms 이하의 속도를 측정할 수 있다. QueryPerfomanceFrequency는 CPU의 클락을 측정하고 QueryPerfomanceCounter에서 클락이 움직인 숫자를 파악해서 얼마가 걸렸는지 측정을 하는 방법이다.

 

QueryPerfomanceCounter를 사용을 하면 보다 정확한 시간을 구할 수는 있긴 하지만, 부하가 Datetime을 쓰는 것보다 높긴 하다.

 

코드는 좋은 예제가 있어서 소개

 

http://www.codeproject.com/Articles/2635/High-Performance-Timer-in-C

 

-------------------------------------------------------------------------------------------------

 

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;

namespace Win32
{
    internal class HiPerfTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(
            out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(
            out long lpFrequency);

        private long startTime, stopTime;
        private long freq;

        // Constructor
        public HiPerfTimer()
        {
            startTime = 0;
            stopTime  = 0;

            if (QueryPerformanceFrequency(out freq) == false)
            {
                // high-performance counter not supported
                throw new Win32Exception();
            }
        }

        // Start the timer
        public void Start()
        {
            // lets do the waiting threads there work
            Thread.Sleep(0);

            QueryPerformanceCounter(out startTime);
        }

        // Stop the timer
        public void Stop()
        {
            QueryPerformanceCounter(out stopTime);
        }

        // Returns the duration of the timer (in seconds)
        public double Duration
        {
            get
            {
                return (double)(stopTime - startTime) / (double) freq;
            }
        }
    }
}