On Sat, 12 Jun 2021 at 12:58, Matt Juntunen <matt.juntu...@hotmail.com> wrote: > > Hello, > > I mentioned a while ago the idea of moving a utility that I find quite useful > from commons-geometry to commons-text, which would be a more appropriate home > for it. There was not any interest at the time but I've made a few > improvements to the class and I'd like to try again. The utility in question > is the DoubleFormats [1] class. This class contains factory methods for > producing lightweight, thread-safe DoubleFunction<String> instances for > converting doubles to decimal strings in different formats. The class is > specifically designed for data output; no localization is performed.
No localisation? Not even decimal point? > It is used in commons-geometry to provide a way to control the precision and > formatting of double values in text-based geometric data formats such as OBJ. > I've found that although the JDK provides a number of different ways to > format doubles (eg, String.format, DecimalFormat, BigDecimal, etc), none of > them have fit the requirements for performant, thread-safe data output. > Hence, the reason for this class. > > Below are examples of each of the types of formats available and some > outputs. The arguments passed to each method are the precision (maximum > number of non-zero decimal digits) and min exponent (base 10 exponent for the > smallest non-zero number that should be represented). > > // plain decimal representation; no scientific format > DoubleFunction<String> plain = DoubleFormats.createPlain(5, -3); > plain.apply(1); // 1.0 > plain.apply(1e10); // 10000000000.0 > plain.apply(1234.567); // 1234.6 > plain.apply(0.00356); // 0.004 > > // scientific format > DoubleFunction<String> sci = DoubleFormats.createScientific(5, -3); > sci.apply(1); // 1.0 > sci.apply(1e10); // 1.0E10 > sci.apply(1234.567); // 1.2346E3 > sci.apply(0.00356); // 4.0E-3 > > // engineering format > DoubleFunction<String> eng = DoubleFormats.createEngineering(5, -3); > eng.apply(1); // 1.0 > eng.apply(1e10); // 10.0E9 > eng.apply(1234.567); // 1.2346E3 > eng.apply(0.00356); // 4.0E-3 > > // default format; uses the Double.toString() convention of representing > // numbers less that 10^-3 or greater than 10^7 using scientific format and > // other numbers using plain decimal format > DoubleFunction<String> def = DoubleFormats.createDefault(5, -3); > def.apply(1); // 1.0 > def.apply(1e10); // 1.0E10 > def.apply(1234.567); // 1234.6 > def.apply(0.00356); // 0.004 > > > The performance of all of these methods is comparable to DecimalFormat or > BigDecimal. The benchmark output below shows the results of formatting 10000 > double values using standard Double.toString(), a simple BigDecimal > conversion, DecimalFormat (single instance), and a function returned from > DoubleFormats.createDefault(). Double.toString() is the clear winner but the > rest are all quite close. > > Benchmark (size) Mode Cnt > Score Error Units > DoubleFormatsPerformance.doubleToString 10000 avgt 5 > 3837610.399 ± 62668.705 ns/op > DoubleFormatsPerformance.bigDecimal 10000 avgt 5 > 6279807.365 ± 93566.619 ns/op > DoubleFormatsPerformance.decimalFormat 10000 avgt 5 > 5787717.633 ± 168626.950 ns/op > DoubleFormatsPerformance.doubleFormatsDefault 10000 avgt 5 > 5779534.166 ± 69496.434 ns/op > > Please let me know if there is any interest in moving this class to > commons-text. It's primary advantages are that it is > -thread-safe (unlike DecimalFormat), > -performant (unlike String.format()), and > -allows a variety of output formats (unlike BigDecimal). > > I would also be open to discussion and improvements on the > design/implementation. > > Regards, > Matt J > > [1] > https://github.com/apache/commons-geometry/blob/master/commons-geometry-io-core/src/main/java/org/apache/commons/geometry/io/core/utils/DoubleFormats.java --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org