Статический метод в экземплярах

Прямой вопрос: если я запускаю анализ кода, он говорит мне делать методы статическими даже в нестатических классах. Насколько мне известно, статические методы создаются с помощью JIT и выполняются на Type-Object в куче. Значит, не будет ли статический метод в нестатическом классе означать, что экземпляр должен искать объект типа в куче и запускать там метод?

Разве это не означало бы проблемы с производительностью? Конечно, это не будет такой уж большой проблемой, но мне все равно это будет интересно.


person Matthias Müller    schedule 12.11.2014    source источник
comment
Возможный дубликат: stackoverflow .com / questions / 874363 /   -  person Philip Pittle    schedule 12.11.2014
comment
Это проблема производительности. Нестатический метод имеет скрытый параметр - ссылку на экземпляр класса. Если ссылка не используется, лучше сделать этот метод статическим, исключив дополнительный параметр метода.   -  person Alex F    schedule 12.11.2014
comment
Также интересно: stackoverflow.com/questions/135020 /   -  person Philip Pittle    schedule 12.11.2014
comment
stackoverflow.com/a/12279898/113683 дает подробное объяснение   -  person Jonny Cundall    schedule 12.11.2014
comment
Если вы планируете использовать статические методы, помните, что статика подразумевает потокобезопасность !!! Статический метод может быть вызван из любого потока в любое время, и только статический метод должен убедиться, что он правильно обрабатывает параллелизм. По этой причине я обычно избегаю статических методов, которые не являются строго необходимыми.   -  person Philip Pittle    schedule 12.11.2014
comment
@PhilipPittle Здравый смысл: если анализ кода говорит ему сделать метод статическим, это потому, что он никогда не ссылается ни на что в объекте - именно так реализуется правило. Это означает, что по определению он не может изменить объект.   -  person TomTom    schedule 12.11.2014
comment
@TomTom - могут возникать дополнительные состояния гонки, которые не имеют ничего общего с объектом хоста. Если статический метод вызывает службу данных (например, базу данных) небезопасным способом, это может вызвать состояние гонки.   -  person Philip Pittle    schedule 12.11.2014
comment
И как бы они вызывали базу данных небезопасным способом? Без того же, применяемого к методам экземпляра (например, с использованием класса статического подключения к базе данных без сохранения потока)? Помните: анализ предлагает сделать методы статическими, потому что ОНИ НЕ ИМЕЮТ СОСТОЯНИЯ ОБЪЕКТА.   -  person TomTom    schedule 12.11.2014


Ответы (3)


Нет, так не работает.

Статический метод на самом деле (незаметно) более эффективен, чем нестатический, потому что (а) ему не передан скрытый указатель this и (б) потому что он статический, фреймворк ничего не должен делать о том, что он виртуальный (хотя этот последний пункт, конечно, также относится и к невиртуальным методам-членам).

Вот подробная статья об обработке типов среды выполнения CLR. В частности просмотрите информацию о таблице методов и таблице слотов методов.

Вот еще хорошая статья Джо Даффи. В ней явно не говорится о статических методах, но объясняется, как вызовы методов выполняются на самом низком (ассемблерном) уровне, чтобы вы могли понять, почему вызов статического метода эффективный.

person Matthew Watson    schedule 12.11.2014
comment
Хорошо, это кажется правильным, но он должен искать объект типа для его выполнения, верно? - person Matthias Müller; 12.11.2014
comment
@ MatthiasMüller Это происходит только в процессе JIT, то есть только один раз за время существования программы. Для получения полной информации ознакомьтесь с этой примерной главой из книги Джеффри Рихтера CLR через книгу C # (поиск при вызове статического метода) - person Matthew Watson; 12.11.2014

Хороший пост о сравнении производительности статических методов с методами экземпляра: Производительность статических методов по сравнению с экземпляром методы

TL; DR:

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

  • Есть редкие случаи, когда статические универсальные методы в другом типе приводят к созданию меньшего количества типов, чем универсальные методы экземпляра, что иногда может иметь небольшое преимущество в том, что он редко используется (и «редко» относится к тем типам, с которыми он используется в время жизни приложения, а не то, как часто оно вызывается). Как только вы поймете, о чем он говорит в этой статье, вы увидите, что в любом случае это на 100% не имеет отношения к большинству решений, связанных со статическим или экземпляром.

person Pavel Krymets    schedule 12.11.2014

Я думаю, дело в том, что вы вызываете статический метод не для экземпляра, а для самого класса. Любой метод, который напрямую не полагается на информацию об экземпляре, может (и на основе анализа кода также должен) быть помечен как статический, а затем вызываться следующим образом:

NonstaticClass.TheStaticMethod();

вместо этого, если это

NonstaticClass inst = new NonstaticClass();
inst.TheStaticMethod();

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

person Thorsten Dittmar    schedule 12.11.2014
comment
Мой вопрос был больше о том, почему его меньше подслушивают, а не больше, поскольку он должен искать тип в куче - person Matthias Müller; 12.11.2014
comment
Ах я вижу. Как ответили другие, дело не в том, чтобы заботиться об указателе this и VMT. - person Thorsten Dittmar; 12.11.2014