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
Post a Comment