Почему разработчики платформы StackOverflow используют статические методы для производительности?
Я читал о технологии StackExchange (например, в этой статье о производительности SO на сайте highavailability.com), и заметили, что они упоминают о тяжелом использовании статического методы повышения производительности.
Почему статические методы работают лучше? Я думаю, что сокращение затрат на сбор мусора связано с этим (поскольку для статических методов не нужны экземпляры); однако есть ли что-то еще?
Ответы
Ответ 1
Основная причина связана с стеком вызовов. В то время как методы экземпляра всегда имеют указатель this
в качестве первых параметров, статические методы не имеют этих накладных расходов.
Это всего лишь миллисекунды (или даже только их фракции в быстрой системе), но они могут складываться в критичных по производительности системах.
Ответ 2
Почему статические методы работают лучше?
Я не думаю, что они это делают. Возможно, есть некоторый выигрыш в GC, если данные, которые передаются статическому методу и возвращаются из него, уходят в стек. В этом случае он не отслеживается GC.
Я запускал программу и получал разные результаты для моих 3 попыток, два раза статический метод был несколько быстрее, 1 раз (показано ниже) метод экземпляра был быстрее. Все данные в пределах разумного диапазона отклонения. Итак, мой вывод: нет заметной разницы, если не принимать во внимание GC.
t1 = 8.0055 ms (instance)
t2 = 8.0119 ms (static)
Вот быстрая тестовая программа
public class Program
{
const int innerMax = 100;
const int outerMax = 1000;
public static void Main()
{
var t1 = new TimeSpan();
var t2 = new TimeSpan();
var program = new Program();
for (int i = 0; i < outerMax; i++)
t1 = program.InstanceAction();
for (int i = 0; i < outerMax; i++)
t2 = StaticAction();
Console.WriteLine("t1 = {0} ms (instance)", t1.TotalMilliseconds);
Console.WriteLine("t2 = {0} ms (static)", t2.TotalMilliseconds);
Console.ReadLine();
}
private TimeSpan InstanceAction()
{
return Time(() => {
var sw = new SpinWait();
for (int i = 0; i < max; i++)
sw.SpinOnce();
});
}
private static TimeSpan StaticAction()
{
return Time(() => {
var sw = new SpinWait();
for (int i = 0; i < innerMax; i++)
sw.SpinOnce();
});
}
private static TimeSpan Time(Action action)
{
Stopwatch stopwatch = Stopwatch.StartNew();
action();
stopwatch.Stop();
return stopwatch.Elapsed;
}
}
Ответ 3
Тяжелое использование статических классов и методов для простоты и лучшего производительность
Если реальные преимущества производительности связаны с конкретной настройкой системы и конкретными метриками, выполненными для конкретной бизнес-области, простота использования классов и методов static
, где это возможно, происходит из:
1) явное проявление потока "только исполнение" в статическом методе
2) easy unit test, поскольку вы имеете дело только с исполнением артефакта (статической функцией)
3) состояние и исполнение являются отдельными и отдельными значениями, поэтому нет проблем с "скрытым состоянием" (статические неизменные вары обычно являются признаком плохого дизайна) или небольшим количеством в противном случае.
В целом, код проще управлять, тестировать и, возможно, понимать.