Ответ 1
Теоретически статический метод должен работать немного лучше, чем метод экземпляра, при прочих равных условиях из-за дополнительного скрытого параметра this
.
На практике это делает так мало различий, что он будет скрыт в шуме различных решений компилятора. (Следовательно, два человека могли бы "доказать" одно лучше другого с несогласованными результатами). Не в последнюю очередь, поскольку this
обычно передается в регистр и часто начинается с этого регистра.
Эта последняя точка означает, что в теории мы должны ожидать, что статический метод принимает объект как параметр и делает что-то с ним немного менее хорошим, чем эквивалент, как экземпляр на том же самом объекте. Опять же, разница настолько незначительна, что, если вы попытались ее измерить, вы, вероятно, в конечном итоге измерили бы какое-то другое решение для компилятора. (Тем более, что вероятность того, что эта ссылка находится в регистре, все время тоже довольно высока).
Реальные различия в производительности снизятся до того, что вы искусственно получили объекты в памяти, чтобы делать что-то, что должно быть естественно статическим, или вы запутываете цепи передачи объектов сложными способами, чтобы делать то, что, естественно, должно быть экземпляром.
Следовательно, для числа 1. Когда сохранение состояния не вызывает беспокойства, всегда лучше быть статичным, , потому что это статическое значение для. Это не проблема производительности, хотя есть общее правило хорошо играть с оптимизацией компилятора - более вероятно, что кто-то пошел на оптимизацию случаев, которые приходят с нормальным использованием, чем те, которые приходят с странным использованием.
Номер 2. Не имеет значения. Там определенная стоимость каждого класса для каждого члена, это условия как количества метаданных там, сколько кода есть в фактическом DLL или EXE файле, и сколько будет jitted-кода. Это то же самое, будь то экземпляр или статический.
С пунктом 3, this
выполняется как this
. Однако обратите внимание:
-
Параметр
this
передается в конкретном регистре. При вызове метода экземпляра в пределах одного класса он, скорее всего, будет в этом регистре (если он не был спрятан и регистр не использовался по какой-либо причине), и, следовательно, не требуется никаких действий, чтобы установитьthis
в том, что ему нужно должен быть установлен. Это в определенной степени относится к, например, первые два параметра для метода являются первыми двумя параметрами вызываемого им вызова. -
Поскольку будет ясно, что
this
не является нулевым, это может быть использовано для оптимизации вызовов в некоторых случаях. -
Поскольку будет ясно, что
this
не является нулевым, это может привести к тому, что вызовы вложенных методов будут более эффективными снова, поскольку код, созданный для подделки вызова метода, может опустить некоторые проверки нулей, которые могут потребоваться в любом случае. -
Тем не менее, нулевые чеки дешевы!
Стоит отметить, что общие статические методы, действующие на объект, а не методы экземпляров, могут уменьшить некоторые из затрат, обсуждаемых в http://www.bluebytesoftware.com/blog/2011/10/23/OnGenericsAndSomeOfTheAssociatedOverheads.aspx в случае, если данный заданный статический не вызывается для данного типа. По его словам, "в стороне, оказывается, что методы расширения - отличный способ сделать родовые абстракции более платными за игру".
Однако обратите внимание, что это относится только к экземпляру других типов, используемых методом, которые иначе не существуют. Таким образом, это действительно не относится ко многим случаям (какой-то другой метод экземпляра использовал этот тип, другой код в другом месте использовал этот тип).
Резюме:
- В основном затраты на производительность экземпляра vs static ниже пренебрежимо малой.
- Какие расходы, как правило, возникают там, где вы, например, злоупотребляете статикой или наоборот. Если вы не сделаете это частью своего решения между статикой и экземпляром, вы, скорее всего, получите правильный результат.
- Существуют редкие случаи, когда статические общие методы в другом типе приводят к созданию меньшего количества типов, чем примеры общих методов, которые могут сделать его иногда небольшим преимуществом для использования редко используемых (и "редко" относится к тем типам, которые он использовал в течение всего срока службы приложения, а не о том, как часто он называется). Как только вы узнаете, о чем он говорит в этой статье, вы увидите, что это 100% не имеет отношения к большинству решений статического vs-экземпляра. Изменить: И в основном это имеет только стоимость с ngen, а не с jitted-кодом.
Изменить: примечание о том, как дешевые нулевые чеки (о чем я говорил выше). Большинство нулевых проверок в .NET вообще не проверяют значение null, скорее они продолжают то, что они собираются делать с предположением, что он будет работать, и если произойдет исключение доступа, оно превратится в NullReferenceException
. Таким образом, в основном, когда концептуально код С# включает проверку нуля, поскольку он обращается к члену экземпляра, стоимость, если он преуспевает, на самом деле равен нулю. Исключением будут некоторые встроенные вызовы (потому что они хотят вести себя так, как если бы они вызывали члена экземпляра), и они просто попали в поле, чтобы вызвать одно и то же поведение, поэтому они также очень дешевы, и их все равно часто можно оставить в любом случае (например, если первый шаг в способе связан с доступом к полю, как он был).