2010-06-10 3 views
19

У меня есть несколько глобальных методов, объявленных в открытом классе в моем веб-приложении ASP.NET.Static Vs Instance Method Performance C#

У меня есть привычка объявить все глобальные методы в общественном классе в следующем формате

public static string MethodName(parameters) { } 

Я хочу знать, как это повлияет на точки зрения производительности?

  1. Какой из них лучше? Статический метод или нестатический метод?
  2. Причина, почему это лучше?

http://bytes.com/topic/c-sharp/answers/231701-static-vs-non-static-function-performance#post947244 состояния:

потому, что статические методы использования блокировок быть потокобезопасным. Всегда делают внутренне Monitor.Enter() и Monitor.exit(), чтобы обеспечить Безопасность потоков.

В то время как http://dotnetperls.com/static-method состояния:

статические методы, как правило, быстрее, чтобы вызвать в стеке вызовов, чем методы экземпляра. Для этого есть несколько причин для этого на языке программирования C# . Методы экземпляров фактически используют указатель экземпляра «this» в качестве первого параметра, поэтому метод экземпляра будет всегда иметь эти служебные данные. Методы экземпляров также реализованы с помощью командыинструкции callvirt на промежуточном языке, которая накладывает небольшие накладные расходы . Обратите внимание, что смена методов на статические методы вряд ли поможет в достижении амбициозных целей производительности, но может немного помочь и, возможно, привести к дальнейшим сокращениям.

Я немного смущен, какой из них использовать?

+0

Вы прочитали до конца этой первой ссылки? Внутри потока становится совершенно ясным, что утверждение об автоматической блокировке ложно. –

ответ

42

Ваша первая ссылка гласит:

Это потому, что статические методы используют замки быть потокобезопасным. Всегда делают Внутренне Monitor.Enter() и Monitor.exit() для обеспечения безопасности потоков

То есть совершенно, ужасно, гнусно неправильно.


Если вы добавите [MethodImpl(MethodImplOptions.Synchronized)] к методу, это утверждение станет частично истинным.

Добавление этого атрибута приведет к тому, что CLR обернется static методами внутри lock(typeof(YourClass)) и методами экземпляра внутри lock(this).

This should be avoided where possible


Ваша вторая ссылка верна.
Static methods are a little bit faster than instance methods, потому что они не имеют параметр this (таким образом, пропуская NullReferenceException чек из инструкции callvirt)

+0

Спасибо Это было полезно. – dotnetguts

+9

+1 для приятных прилагательных :) – SWeko

5

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

+0

Очень хорошая точка. –

0

Это в основном выбор дизайна. Если у вас есть логика, которая включает создание экземпляра класса и обновление некоторых свойств, перейдите для метода экземпляра, поскольку статический метод будет использоваться совместно с экземплярами. Хотя, если у вас есть некоторые полезные функции, такие как выполнение некоторых строковых манипуляций, создание строки подключения и т. Д., Которая не связана с манипуляциями с объектом, перейдите для статического метода.

2

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

Существуют и другие способы повышения производительности вашего приложения.

некоторые примеры:

  • Если вы хотите использовать простой метод несколько раз без инстансов объекта каждый раз (вспомогательная функция), а затем использовать статический метод в статическом классе.

  • Если ваш метод получает доступ к другим переменным в классе и не использует поточную функцию s-член.

  • В asp.net, если вы хотите разделить объект по сеансам или вы можете повысить производительность с помощью метода, который внутренне кэширует результат, статический метод тоже будет хорош.

  • Вы можете смешивать оба способа и использовать шаблон фабричного проектирования, чтобы иметь класс с некоторыми функциями-членами, но вы гарантируете, что всегда есть только один экземпляр за раз.

  • Иногда статическая функция может избежать глупых ошибок или уменьшает необходимость дополнительных проверок во время выполнения:

    String.IsNullOrEmpty(thisstringisnull) // returns true 
    thisstringisnull.IsNullOrEmpty() // If Microsoft would have implemented 
               // the method this way you would get a 
               // NullReferenceException 
    

Но в целом это полностью зависит от текущей задачи. Нелегко «всегда использовать этот подход ...» ответ на ваш вопрос.

+0

Спасибо SchlaWiener за ответ. Я объявляю утилиты, которые используются много раз и хороши из ремонтопригодного подхода, но я был смущен блокировкой метода, как упоминалось в одном потоке. – dotnetguts

+0

На самом деле у вас могут быть методы расширения, которые теперь работают с нулевыми значениями, поэтому thisstringisnull.IsNullOrEmpty() может иметь смысл. – SWeko

+0

@SWeko: действительно? не знал об этом. Это верно для каждого метода расширения или мне нужно добавить дополнительный код, если я напишу метод расширения? –

Смежные вопросы