Однажды я опрометчиво попытался оптимизировать Class.resolveName(), опираясь на результаты теста (доступного в указанном PR), воспроизводящего логику упомянутого метода. Идея оптимизации была довольно тривиальной и заключалась в замене new StringBuilder().append() простой конкатенацией. Оказалось, что, хотя тест показал значительное улучшение, сам исправленный метод ухудшился. Как было отмечено в комментариях PR
Тест JMH может показать лучшие результаты, поскольку он скомпилирован в байт-код, который
использует специальную конкатенацию строк на основе вызова, основанную на динамическом вызове, с оптимальной базовой стратегией,
на основе MH. Код в java.lang.Class не может быть скомпилирован
для использования такого рода конкатенации из-за проблем с начальной загрузкой, и поэтому он
компилируется в байт-код, который напрямую использует StringBuilder (очень
как и существующий код исправленного метода).
Действительно, конкатенация строк в java.base компилируется в StringBuilder байт-код в отличие от клиентского кода (там они используют ignoredynamic вместе со StringConcatFactory).
Я исследовал эти «проблемы начальной загрузки», но единственное, что я нашел, — это порядок загрузки классов. Если запустить java -Xlog:class+init -version, становится ясно, что StringConcatFactory загружается намного позже j.l.Class. В то же время после него загружается множество других классов, на которые ссылается j.l.Class.
Поэтому у меня вопрос: почему javac может использовать e. г. StringBuilder внутри Class.resolveName(), но не StringConcatFactory? Что такого особенного в этом классе?
Или, может быть, мои предположения ошибочны, и проблема с начальной загрузкой связана не со StringConcatFactory и ignoredynamic?