【发布时间】:2015-12-16 13:47:39
【问题描述】:
我正在学习多线程,发现在多线程环境中Object.hashCode 的速度变慢了,因为它需要两倍的时间来计算运行 4 threads 与 1 thread 相同数量对象的默认哈希码.
但根据我的理解,并行执行此操作应该花费类似的时间。
您可以更改线程数。每个线程都有相同的工作量,因此您希望在我的四核机器上运行 4 个线程可能与运行单个线程所需的时间大致相同。
我看到 4x 大约 2.3 秒,但 1x 大约 0.9 秒。
我的理解是否有任何差距,请帮助我理解这种行为。
public class ObjectHashCodePerformance {
private static final int THREAD_COUNT = 4;
private static final int ITERATIONS = 20000000;
public static void main(final String[] args) throws Exception {
long start = System.currentTimeMillis();
new ObjectHashCodePerformance().run();
System.err.println(System.currentTimeMillis() - start);
}
private final ExecutorService _sevice = Executors.newFixedThreadPool(THREAD_COUNT,
new ThreadFactory() {
private final ThreadFactory _delegate = Executors.defaultThreadFactory();
@Override
public Thread newThread(final Runnable r) {
Thread thread = _delegate.newThread(r);
thread.setDaemon(true);
return thread;
}
});
private void run() throws Exception {
Callable<Void> work = new java.util.concurrent.Callable<Void>() {
@Override
public Void call() throws Exception {
for (int i = 0; i < ITERATIONS; i++) {
Object object = new Object();
object.hashCode();
}
return null;
}
};
@SuppressWarnings("unchecked")
Callable<Void>[] allWork = new Callable[THREAD_COUNT];
Arrays.fill(allWork, work);
List<Future<Void>> futures = _sevice.invokeAll(Arrays.asList(allWork));
for (Future<Void> future : futures) {
future.get();
}
}
}
对于线程数为 4 的输出为
~2.3 seconds
对于线程数为 1 的输出为
~.9 seconds
【问题讨论】:
-
请分享您在 1 到 4 个线程之间所做的更改
-
这里的时间测量不一定能告诉你太多。见stackoverflow.com/questions/504103/…
-
你可能没有测量正确的东西:GC、创建执行器及其线程、线程协调、对象实例化、内存分配等等。无论如何,beanchmark 是非常没用的,因为无论如何您都无法对 Object 的 hashCode() 实现进行任何更改。
-
您不是在测量 hashCode(),而是在单线程时测量 2000 万个对象的实例化,在运行 4 个线程时测量 8000 万个对象。将新的 Object() 逻辑移出 Callable 中的 for 循环,然后您将测量 hashCode()
-
此外,对象的 hashCode 实际上是通过本地平台特定调用实现的,因此您可能不会发现任何性能问题。
标签: java multithreading executorservice microbenchmark