Более быстрая альтернатива DecimalFormat.format()?

Чтобы улучшить производительность, я профилировал одно из моих приложений с помощью VisualVM sampler, используя минимальный период выборки 20 мс. Согласно профилировщику, главный поток тратит почти четверть своего процессорного времени на метод DecimalFormat.format() .

Я использую DecimalFormat.format() с шаблоном 0.000000 для "преобразования" двойных чисел в строковое представление с ровно шестью десятичными цифрами. Я знаю, что этот метод относительно дорогой и его вызывают много раз, но я все равно был несколько удивлен этими результатами.

  1. В какой степени результаты такого профилировщика выборки точны? Как я могу проверить их - желательно не прибегая к инструментальному профилировщику?

  2. Есть ли более быстрая альтернатива 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() все еще самый быстрый среди этих альтернатив.

17
задан thkala 18 December 2011 в 20:57
поделиться