Чтобы повысить производительность, я профилировал одно из своих приложений с помощью пробоотборника VisualVM, используя минимальный период выборки 20 мс. Согласно профилировщику, основной поток затрачивает почти четверть своего процессорного времени в метод DecimalFormat.format()
.
Я использую DecimalFormat.format()
с шаблоном 0.000000
для "преобразования" double
чисел в строковое представление с ровно шестью десятичными цифрами. Я знаю, что этот метод относительно дорог, и его называют много раз, но я все еще несколько удивлялся этим результатам.
-
В какой степени результаты такого профилирования выборки точны? Как я буду проверять их - предпочтительнее, не прибегая к инструментальному профилировщику?
-
Есть ли более быстрая альтернатива
DecimalFormat
для моего варианта использования? Имеет смысл развернуть мой собственный подклассNumberFormat
?
UPDATE:
Я создал микро-тест для сравнения производительности следующих трех методов:
-
DecimalFormat.format()
: Один объектDecimalFormat
повторно используется несколько раз. -
String.format()
: несколько независимых вызовов. Внутренне этот метод сводится кpublic static String format(String format, Object ... args) { return new Formatter().format(format, args).toString(); }
Поэтому я ожидал, что его производительность будет очень похожа на
Formatter.format()
. -
Formatter.format()
: Один объектFormatter
повторно используется несколько раз.Этот метод немного неудобен -
Formatter
объекты, созданные с помощью конструктора по умолчанию, присоединяют все строки, созданные методомformat()
, к внутреннему объектуStringBuilder
, который не является надлежащим образом доступным и поэтому не может быть очищен. Как следствие, несколько вызововformat()
создадут конкатенацию всех результирующих строк.Чтобы обойти эту проблему, я предоставил свой собственный экземпляр
StringBuilder
, который я удалил перед использованием с вызовомsetLength(0)
.
Результаты, интересные:
-
DecimalFormat.format()
был базовым значением в 1,4 раза за звонок. -
String.format()
был медленнее в два раза по 2,7 раза за звонок. -
Formatter.format()
также был медленнее в два раза по 2,5 раза за звонок.
Сейчас кажется, что DecimalFormat.format()
по-прежнему самый быстрый среди этих альтернатив.