java - What are the performance impacts of using DecimalFormat with ThreadLocal? -


i have implementation uses decimalformat(https://docs.oracle.com/javase/7/docs/api/java/text/decimalformat.html) api.

solution1: argument because decimalformat not thread-safe, inclined use threadlocal decimalformat creation make thread safe. also, save creation of decimalformat object each invocation

private static final threadlocal<decimalformat> restrictto1decimalplace =             threadlocal.withinitial                     (() -> new decimalformat("0.0%", decimalformatsymbols.getinstance(locale.english))); 

solution 2: simple solution give away object reusability , create object of decimalformat everytime.

new decimalformat("0.0%", decimalformatsymbols.getinstance(locale.english)).format(decimalvaluetoformat) 

what better?

in applications, difference not matter, you'll want simpler option.

you can verify benchmarking both alternatives:

public abstract class benchmark {      public static void main(string[] args) throws exception {         final threadlocal<decimalformat> restrictto1decimalplace =                 threadlocal.withinitial                         (() -> new decimalformat("0.0%", decimalformatsymbols.getinstance(locale.english)));                     benchmark[] marks = {             new benchmark("threadlocal") {                 @override                 protected object run(int iterations) throws throwable {                     stringbuilder sb = new stringbuilder();                     (int = 0; < iterations; i++) {                         sb.append(restrictto1decimalplace.get().format(i * 0.01));                     }                     return sb;                 };             },             new benchmark("new format") {                 @override                 protected object run(int iterations) throws throwable {                     stringbuilder sb = new stringbuilder();                     (int = 0; < iterations; i++) {                         sb.append(new decimalformat("0.0%", decimalformatsymbols.getinstance(locale.english)).format(i * 0.01));                     }                     return sb;                 };             },         };         (benchmark mark : marks) {             system.out.println(mark);         }     }      final string name;      public benchmark(string name) {         this.name = name;     }      @override     public string tostring() {         return name + "\t" + time() + " ns / iteration";     }      private bigdecimal time() {         try {             // automatically detect reasonable iteration count (and trigger in time compilation of code under test)             int iterations;             long duration = 0;             (iterations = 1; iterations < 1_000_000_000 && duration < 1_000_000_000; iterations *= 2) {                 long start = system.nanotime();                 run(iterations);                 duration = system.nanotime() - start;             }             return new bigdecimal((duration) * 1000 / iterations).movepointleft(3);         } catch (throwable e) {             throw new runtimeexception(e);         }     }      /**      * executes code under test.      * @param iterations      *            number of iterations perform      * @return value requires entire code executed (to      *         prevent dead code elimination in time compiler)      * @throws throwable      *             if test not complete      */     protected abstract object run(int iterations) throws throwable; } 

on machine, prints:

threadlocal 260.132 ns / iteration new format  363.199 ns / iteration 

so difference between getting format threadlocal or creating new 1 0.0000001 seconds. unless application formats millions of strings every second, not worth thinking :-)


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -