简体   繁体   中英

Use DecimalFormat with StringBuilder

What is the most efficient way to use an instance of DecimalFormat together with a StringBuilder ? When numbers are appended to a string in a loop, for example. There is format(long number, StringBuffer toAppendTo, FieldPosition pos) , but that uses a StringBuffer and not a StringBuilder , so it is not compatible, and there is also formatToCharacterIterator(Object obj) but that both must create an object for the iterator and does not work with primitive types, so it also requires additional potential boxing.

It seems to me calling format(long number) to produce a string and append it to the StringBuilder is the easiest option, but having to create a string just to append it seems to be kinda defeating the purpose of the StringBuilder . Is there really no other option?

Edit: I have decided to do some measurements to see the performance difference between these options. Based on the OpenJDK implementation, it seems all methods eventually get routed to either format(long, StringBuffer, FieldPosition) or format(double, StringBuffer, FieldPosition) (with the exception of large BigInteger and BigDecimal ), so it would seem when appending just numbers, this way will always be faster with StringBuffer .

And indeed, directly using StringBuffer is about 20 % faster on my machine than via StringBuilder and intermediate string. However, the opposite is true when no number formatting is done and only strings are appended – then StringBuffer is 20 % slower. But considering formatting a number is about 5 times slower than simply appending a string, StringBuilder seems to be only ever more efficient when there are significantly more appends than formats.

Unless you can ascertain that the additional String and StringBuffer creation is an actual real-world bottleneck in your application, I suspect you are worrying unnecessarily. It's true that if we could re-invent the history of the JDK, these calls probably would have been defined as taking Appendable. But the authors may well have considered adding a corresponding method when StringBuilder and Appendable were added in Java 5 and decided it was not worth it.

Remember that in modern JVMs, the creation and disposal of temporary objects doesn't have the performance overhead that it once used to. In addition, various flavours of NumberFormat-- including DecimalFormat-- actually provide an internal 'fast path' (see the fastFormat() method) that avoids the StringBuffer creation you mention (though not the temporary String creation). The JVM also generally optimises for uncontended synchronisation as you will have here.

If a profile genuinely shows that DecimalFormat.foramt() is a bottleneck to your application, then there is a chance you may need to consider implementing a specific method to include the optimisations you require. But I suspect you'll find that it's not actually an issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM