Welcome to Dynamic C#(4) - 극과극 비교체험.

C# 2009. 8. 20. 20:25 Posted by 알 수 없는 사용자

- 또 쓸데없는 생각 하냐?

안녕하세요. 정말 오랜만입니다. 사연이 많은 사람이다 보니, 잠수를 자주 타게 되네열. -_-;;;;; 그래서 뭐라도 써야한다는 생각을 하다가, 별로 쓸모있을진 모르겠지만, 실행속도를 비교해보자는 생각이 들었습니다. 짧은 글이 되겠지만, 조금이라도 도움이 되길바라면숴!


- 빨랑 비교한거 내놔.

비교대상은 한 클래스에 있는 메서드를 그냥 호출하는 것과 dynamic을 통해 호출하는 것, 그리고 리플렉션을 통해서 호출하는 세가지방법입니다. 그리고 각 호출을 메서드를 10만, 50만, 100만, 300만, 500만번 호출하는 것으로 속도를 재어봤습니다. 실행의 대상이 된 코드는 아래와 같습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication2
{
    class Test
    {
        public int FivePlusFive()
        {
            return 10;
        }
    }

    class Program
    {
        public void ReflectionCall()
        {
            object test = new Test();
            Type type = test.GetType();
            type.InvokeMember("FivePlusFive", System.Reflection.BindingFlags.InvokeMethod, (Binder)null,
                test, new object[] {});
        }

        public void DynamicCall()
        {
            dynamic test = new Test();
            test.FivePlusFive();
        }

        public void NormalCall()
        {
            Test test = new Test();
            test.FivePlusFive();
        }

        static void Main(string[] args)
        {
            Program prog = new Program();

            //for JIT compile
            prog.ReflectionCall();
            prog.DynamicCall();
            prog.NormalCall();

            long limit = 5000000;

            DateTime normalStart = DateTime.Now;
            for (int i = 0; i < limit; i++)
            {
                prog.NormalCall();
            }
            DateTime normalEnd = DateTime.Now;
            TimeSpan normalResult = normalEnd - normalStart;

            DateTime dynamicStart = DateTime.Now;
            for (int i = 0; i < limit; i++)
            {
                prog.DynamicCall();
            }
            DateTime dynamicEnd = DateTime.Now;
            TimeSpan dynamicResult = dynamicEnd - dynamicStart;

            DateTime reflectionStart = DateTime.Now;
            for (int i = 0; i < limit; i++)
            {
                prog.ReflectionCall();
            }
            DateTime reflectionEnd = DateTime.Now;
            TimeSpan reflectionResult = reflectionEnd - reflectionStart;

            Console.WriteLine("Normal Time : {0}", normalResult);
            Console.WriteLine("Dynamic Time : {0}", dynamicResult);
            Console.WriteLine("Reflection Time : {0}", reflectionResult);
        }
    }
}



JIT컴파일에 걸리는 시간을 빼기 위해서 일단 한번씩 먼저 실행했구요, 각각의 방법을 정해진 횟수만큼 실행해서 시간을 측정하는 방식으로 했습니다. 그럼 결과를 보시져!!!! 야호!!!! 완전 신나!!!! -_-......

- 10만번

- 50만번

- 100만번

- 300만번

- 500만번


그리고 위의 결과를 표로 종합해보면 아래와 같습니다.


일반 호출은 리플렉션에 비해서 너무 작아서 그런지 아예 나타나지도 않는군요-_-;;;; 별로의미있는 코드로 실험을 한건 아니지만, 다이나믹이 리플렉션에 비해서는 월등히 빠르군요. 아마도 DLR의 힘을 빌려서 리플렉션 보다 훨씬 빠른 방식을 이용하는 것 같습니다. 이 부분에 대해서는 좀 조사를 해봐야 할거 같네요.


- 피드백 및 정정사항!!ㅋ

이 글을 보시고 정성태님께서 피드백을 주셨습니다.(http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&detail=1&pageno=0&wid=766&rssMode=1&wtype=0) 정성태님의 블로그를 들르면서 내공의 깊이에 감탄을 하곤했는데, 직접 피드백을 받으니 더 확실하네 느껴지네요^^ㅋ. 글의 내용을 보시면, 제가 단순히 리플렉션 호출을 반복하게 설정해놓은 것에서 리플렉션에 매우 불리한 결과가 도출되는 요인이 있음을 지적하시고, 더 빠르게 그리고 오히려 다이나믹 보다도 더 빠른 결과가 나올 수 있는 방식을 제시해주고 계십니다.

잘 몰랐던 부분에 대해서 지적해주셔서 좋은거 배웠네요~.


- 마치면서

별로 내용도 없는 글을 썼군요-_-;;; 다음 포스트부터는 dynamic에 대해서 좀 더 심도 깊게 파보려고 생각중입니다. 좋은글이 많은데 잠수타고 정신줄 놓느라고 못보고 있었더군요!! 암튼. 곧 돌아오겠슴돠. ㅋㅋㅋ