简体   繁体   English

将 DecimalFormat 与 StringBuilder 一起使用

[英]Use DecimalFormat with StringBuilder

What is the most efficient way to use an instance of DecimalFormat together with a StringBuilder ?DecimalFormat的实例与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.format(long number, StringBuffer toAppendTo, FieldPosition pos) ,但它使用StringBuffer而不是StringBuilder ,所以它不兼容,还有formatToCharacterIterator(Object obj)但两者都必须为迭代器创建一个对象和不适用于原始类型,因此它还需要额外的潜在装箱。

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 .在我看来,调用format(long number)来生成一个字符串并将其附加到StringBuilder是最简单的选择,但是必须创建一个字符串来附加它似乎有点违背了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 .基于OpenJDK实现,似乎所有方法最终都会被路由到format(long, StringBuffer, FieldPosition)format(double, StringBuffer, FieldPosition) (大BigIntegerBigDecimal除外),因此在附加时看起来数字,这种方式使用StringBuffer总是更快。

And indeed, directly using StringBuffer is about 20 % faster on my machine than via StringBuilder and intermediate string.事实上,在我的机器上直接使用StringBuffer比通过StringBuilder和中间字符串快大约 20%。 However, the opposite is true when no number formatting is done and only strings are appended – then StringBuffer is 20 % slower.然而,当没有进行数字格式化并且只附加字符串时,情况正好相反——那么StringBuffer会慢 20%。 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.但是考虑到格式化一个数字比简单地附加一个字符串慢 5 倍, StringBuilder似乎只有在附加比格式多得多的情况下才会更有效率。

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.除非您能确定额外的 String 和 StringBuffer 创建是您的应用程序中实际的实际瓶颈,否则我怀疑您是不必要的担心。 It's true that if we could re-invent the history of the JDK, these calls probably would have been defined as taking Appendable.的确,如果我们可以重新发明 JDK 的历史,这些调用可能会被定义为采用 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.但是当 Java 5 中添加 StringBuilder 和 Appendable 时,作者可能已经考虑添加相应的方法,并认为不值得。

Remember that in modern JVMs, the creation and disposal of temporary objects doesn't have the performance overhead that it once used to.请记住,在现代 JVM 中,临时对象的创建和处置没有它曾经使用过的性能开销。 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).此外,各种类型的 NumberFormat - 包括 DecimalFormat - 实际上提供了一个内部“快速路径”(请参阅​​ fastFormat() 方法),以避免您提到的 StringBuffer 创建(尽管不是临时 String 创建)。 The JVM also generally optimises for uncontended synchronisation as you will have here. JVM 通常也会优化无竞争同步,正如您将在此处看到的那样。

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.如果配置文件确实表明 DecimalFormat.foramt() 是您的应用程序的瓶颈,那么您可能需要考虑实施特定方法以包含您需要的优化。 But I suspect you'll find that it's not actually an issue.但我怀疑你会发现这实际上不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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