2011-02-03 5 views
8

내가 로그 클래스와 다음 코드에서와 같이 함수를 작성했습니다 :MethodBase.GetCurrentMethod() 성능?

Log(System.Reflection.MethodBase methodBase, string message) 

나는 또한 methodBase.Name 및 methodBase.DeclaringType.Name에서 클래스 이름을 기록 뭔가를 기록 할 때마다.

다음 게시물 Using Get CurrentMethod을 읽고이 방법이 느리다는 것을 알았습니다.

System.Reflection.MethodBase 대신 this.GetType()을 사용해야합니까, 아니면 수동으로 클래스/메소드 이름을 로그에 기록해야합니다. 가장 좋은 방법은 무엇 로그 ("ClassName.MethodName", "메시지 로그는)?

+0

@loannis와 비슷한 질문이 여기에 있습니다. 링크를 확인하십시오. http://stackoverflow.com/questions/1466740/using-getcurrentmethod-in-supposedly-high-performance-code – RameshVel

+0

daniels에서 "this.GetType()은 호출 당 2.5 ns가 필요하고 MethodBase.GetCurrentMethod()는 필요합니다. .DeclaringType은 호출 당 2490 ns를 필요로하므로 약 1200 배의 속도가 향상됩니다. " – RameshVel

+0

@Ramesh : 그 질문에 이미 링크되어있는 것과 정확히 동일한 질문이 있음을 알았습니까? –

답변

9

정말 따라 달라집니다.

당신이 this.GetType() 접근 방식을 사용하는 경우이 방법 정보를 잃게됩니다,하지만 당신은 큰있을 것이다 (귀하의 링크에 따라 외관상으로 1200의 팩터)

호출자가 문자열을 제공 할 수있는 인터페이스를 제공하면 (예 : Log("ClassName.MethodName", "log message"), 더 나은 성능을 얻을 수는 있지만 API가 덜 친숙 해집니다. 호출하는 개발자는 클래스 이름과 메소드 이름을 제공해야합니다.)

2
Reflection Time: 1692.1692ms 
    Lookup Time: 19.0019ms 

Press Enter to exit 
:나는이 오래된 질문이다 알지만, 내가 잘 수행 할 것으로 보인다 간단한 솔루션을 던질 거라고 생각하고 유지 상징

static void Main(string[] args) 
    { 
     int loopCount = 1000000; // 1,000,000 (one million) iterations 
     var timer = new Timer(); 

     timer.Restart(); 
     for (int i = 0; i < loopCount; i++) 
      Log(MethodBase.GetCurrentMethod(), "whee"); 
     TimeSpan reflectionRunTime = timer.CalculateTime(); 

     timer.Restart(); 
     for (int i = 0; i < loopCount; i++) 
      Log((Action<string[]>)Main, "whee"); 
     TimeSpan lookupRunTime = timer.CalculateTime(); 

     Console.WriteLine("Reflection Time: {0}ms", reflectionRunTime.TotalMilliseconds); 
     Console.WriteLine(" Lookup Time: {0}ms", lookupRunTime.TotalMilliseconds); 
     Console.WriteLine(); 
     Console.WriteLine("Press Enter to exit"); 
     Console.ReadLine(); 

    } 

    public static void Log(Delegate info, string message) 
    { 
     // do stuff 
    } 

    public static void Log(MethodBase info, string message) 
    { 
     // do stuff 
    } 

    public class Timer 
    { 
     private DateTime _startTime; 

     public void Restart() 
     { 
      _startTime = DateTime.Now; 
     } 

     public TimeSpan CalculateTime() 
     { 
      return DateTime.Now.Subtract(_startTime); 
     } 
    } 

이 코드를 실행하면 다음과 같은 결과가 날 수 있습니다

백만 회 반복의 경우 특히 입니다. 특히 직선 반향과 비교하면 좋습니다. 메서드 그룹이 대리자 형식으로 캐스트되고 있으면 로깅에 대한 모든 방법으로 심볼 링크가 유지됩니다. 구피 마술 끈이 없어.

+1

게시 한 정확한 코드에 계산을 기반으로하는 경우 Log 메서드 자체에서 실제로 발생하는 것이 없기 때문에 위임 경로의 사용 시간이 더 짧을 것으로 기대하지 않을 것입니다. 실제로 아무것도하지 않습니까? 당신은 실제로 당신이'Log (Delegate info ...') 메소드에 전달할 메소드의 이름을 얻을 수 있습니까? – Zack

+1

@Zack이 예상대로 Log 메소드의 Name 속성에 액세스하면 차이점은 각각'MethodBase.Name'과'Delegate.Method.Name'을 반환하도록 수정했고 결과는'Reflection Time : 1178,6813ms Lookup Time : 482,2953ms'가되었습니다. 여전히 "Lookup"- 접근 방식이 빠른 실행을 유도합니다. –