2011-02-03 5 views
8

Я написал класс журнала и функции, как в следующем коде:Свойство MethodBase.GetCurrentMethod()?

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

Каждый раз, когда я вхожу что-то я войти имя класса из methodBase.Name и methodBase.DeclaringType.Name.

Я прочитал следующее сообщение Using Get CurrentMethod, и я заметил, что этот метод медленный.

Должен ли я использовать this.GetType() вместо System.Reflection.MethodBase или я должен вручную зарегистрировать имя класса/метода в своем журнале, например. Log («ClassName.MethodName», «сообщения журнала)? Что такое лучшая практика?

+0

@loannis, вопрос здесь задал. Проверьте ссылку http://stackoverflow.com/questions/1466740/using-getcurrentmethod-in-supposedly-high-performance-code – RameshVel

+0

От daniels ответьте «this.GetType() потребовалось 2,5 нс на звонок, а MethodBase.GetCurrentMethod() .DeclaringType требуется 2490 нс за звонок - так что у вас есть скорость около фактора 1200. " – RameshVel

+0

@Ramesh: Вы заметили, что это был тот же вопрос (ы), с которым он уже связан в вопросе? –

ответ

9

Это действительно зависит.

Если вы используете this.GetType() подход, вы потеряете информацию метод, но вы будете иметь большой (по-видимому, коэффициент 1200, согласно вашей ссылке).

Если вы предлагаете интерфейс, который позволяет подавать строки звонящего (например, Log("ClassName.MethodName", "log message"), вы, вероятно, получите еще лучшую производительность, но это сделает ваш интерфейс менее дружественным (вызывающий разработчик должен указать имя и имя класса).

2

Я знаю, что это старый вопрос, но я решил выбросить простое решение, которое, кажется, хорошо работать и поддерживает символы

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); 
     } 
    } 

Выполнение этого кода дает мне следующие результаты:

Reflection Time: 1692.1692ms 
    Lookup Time: 19.0019ms 

Press Enter to exit 

На миллион итераций, это неплохо на всех, особенно по сравнению с прямым отражением. Группа методов добавляется к типу Delegate, вы поддерживаете символическую связь до входа в журнал. Нет тупой магической струны.

+1

Если вы основываете свои расчеты на точный код, который вы опубликовали, ничего не происходит в самих методах журнала, разве вы не ожидаете, что маршрут делегата будет использовать меньше времени, потому что он на самом деле ничего не делает? Действительно ли вы можете получить имя метода, который вы передаете, в метод «Log (Делегировать информацию ...»? – Zack

+1

Как и ожидалось, ожидается, что доступ к свойству Name в Log-методах я изменил их, чтобы вернуть 'MethodBase.Name' и' Delegate.Method.Name' соответственно. Мои результаты затем стали «Reflection Time: 1178,6813ms Lookup Time: 482,2953ms'. Тем не менее,« Lookup »- подход ведет к более быстрому выполнению. –