Чтобы улучшить производительность, я профилировал одно из моих приложений с помощью VisualVM sampler, используя минимальный период выборки 20 мс. Согласно профилировщику, главный поток тратит почти четверть своего процессорного времени на метод DecimalFormat.format()
.
Я использую DecimalFormat.format()
с шаблоном 0.000000
для "преобразования" двойных
чисел в строковое представление с ровно шестью десятичными цифрами. Я знаю, что этот метод относительно дорогой и его вызывают много раз, но я все равно был несколько удивлен этими результатами.
В какой степени результаты такого профилировщика выборки точны? Как я могу проверить их - желательно не прибегая к инструментальному профилировщику?
Есть ли более быстрая альтернатива 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()
все еще самый быстрый среди этих альтернатив.