gpt4 book ai didi

java - 将 DecimalFormat 与 ThreadLocal 结合使用会对性能产生哪些影响?

转载 作者:行者123 更新时间:2023-12-02 02:41:32 28 4
gpt4 key购买 nike

我有一个使用 DecimalFormat( https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html ) API 的实现。

解决方案1:这个论点是因为DecimalFormatNOT线程安全的,我倾向于使用ThreadLocal用于 DecimalFormat 创建以使其线程安全。此外,它将保存每次调用的 DecimalFormat 对象的创建

private static final ThreadLocal<DecimalFormat> restrictTo1DecimalPlace =
ThreadLocal.withInitial
(() -> new DecimalFormat("0.0%", DecimalFormatSymbols.getInstance(Locale.ENGLISH)));

解决方案 2:另一个简单的解决方案是放弃对象的可重用性并每次都创建 DecimalFormat 对象。

new DecimalFormat("0.0%", DecimalFormatSymbols.getInstance(Locale.ENGLISH)).format(decimalValueToFormat)

什么更好?

最佳答案

在大多数应用程序中,差异并不重要,因此您需要更简单的选项。

您可以通过对两种替代方案进行基准测试来验证这一点:

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();
for (int i = 0; i < 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();
for (int i = 0; i < iterations; i++) {
sb.append(new DecimalFormat("0.0%", DecimalFormatSymbols.getInstance(Locale.ENGLISH)).format(i * 0.01));
}
return sb;
};
},
};
for (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 a reasonable iteration count (and trigger just in time compilation of the code under test)
int iterations;
long duration = 0;
for (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 the code under test.
* @param iterations
* number of iterations to perform
* @return any value that requires the entire code to be executed (to
* prevent dead code elimination by the just in time compiler)
* @throws Throwable
* if the test could not complete successfully
*/
protected abstract Object run(int iterations) throws Throwable;
}

在我的机器上,打印:

ThreadLocal 260.132 ns / iteration
new Format 363.199 ns / iteration

因此,从 ThreadLocal 获取格式或创建新格式之间的差异约为 0.0000001 秒。除非您的应用程序每秒格式化数百万个字符串,否则不值得考虑:-)

关于java - 将 DecimalFormat 与 ThreadLocal 结合使用会对性能产生哪些影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45370011/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com