jfree / jfreesvg

A fast, lightweight Java library for creating Scalable Vector Graphics (SVG) output.
http://www.jfree.org/jfreesvg
GNU General Public License v3.0
319 stars 58 forks source link

Faster double-to-string conversion #54

Closed ghost closed 1 year ago

ghost commented 1 year ago

Hi again,

I'll leave this here.

/**
 * Responsible for converting a double value into a string with a specified
 * precision.
 */
public final class FastDouble {
  private static final int[] POW10 = {1, 10, 100, 1000, 10000, 100000, 1000000};
  private static final StringBuilder BUFFER = new StringBuilder();

  /**
   * Converts the given value to a string.
   *
   * @param value     The value to convert to a string.
   * @param precision The number of decimal places.
   * @return The string representation of the given value.
   * @see <a href="https://stackoverflow.com/a/10554128/59087">source</a>
   */
  public static String toString( double value, final int precision ) {
    assert precision >= 0;
    assert precision < POW10.length;

    final var sb = BUFFER;
    sb.setLength( 0 );

    if( value < 0 ) {
      sb.append( '-' );
      value = -value;
    }

    final int exp = POW10[ precision ];
    final long lval = (long) (value * exp + 0.5);

    sb.append( lval / exp ).append( '.' );

    final long fval = lval % exp;

    for( int p = precision - 1; p > 0 && fval < POW10[ p ]; p-- ) {
      sb.append( '0' );
    }

    sb.append( fval );

    return sb.toString();
  }
}

Feel free to benchmark it against RyuDouble. Depending on the precision, this could be a faster replacement.

Note: This isn't thread safe, but that can be changed by moving the buffer allocation into the method itself.