什么时候并行执行任务是矫枉过正?
When does performing tasks in parallel is an overkill?
我有一段 java 代码,它从 xml 构造一个对象,根据对象大小需要几纳秒到一毫秒。有时我必须调用该方法 1-2 次,有时循环调用 70-80 次以构建对象列表。
我尝试并行构建对象,但有时它花费的时间是顺序构建的两倍,其他时间的一半。现在我的问题是,是否有任何指导方针或性能比较指标来指导何时应该使用多任务处理以及何时使用多任务处理?
我使用的示例代码是:
List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();
for (final Integer object : list) {
Callable<Integer> c = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return test.m1(object);
}
};
tasks.add(c);
}
List<Future<Integer>> results = EXEC.invokeAll(tasks);
for (Future<Integer> fr : results) {
fr.get();
}
简短回答:当您没有性能或 IO 阻塞问题时,它就太过分了。
关于并行性能的几个因素是:
- 任务之间需要多少communication/coordination。请参阅 Embarrassingly parallel 以了解最少协调的示例。
- 并行处理的结构需要时间来创建。例如 OSX Thread takes about 90 microseconds 将被创建,因此您至少需要保存那么多(如果您创建一个)。
- 并行处理不会加速连续分数。如果任务需要一个小时,并且只有 75% 的任务可以并行处理,那么您将无法在 15 分钟内完成它。参见 Amdahl's law。
看看 Doug Lea 的 post "When to use parallel streams"。
当并行计算开始有意义时,粗略估计(在十倍内)是 100 微秒 顺序执行。尽管还有更多因素需要考虑。
我有一段 java 代码,它从 xml 构造一个对象,根据对象大小需要几纳秒到一毫秒。有时我必须调用该方法 1-2 次,有时循环调用 70-80 次以构建对象列表。
我尝试并行构建对象,但有时它花费的时间是顺序构建的两倍,其他时间的一半。现在我的问题是,是否有任何指导方针或性能比较指标来指导何时应该使用多任务处理以及何时使用多任务处理?
我使用的示例代码是:
List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();
for (final Integer object : list) {
Callable<Integer> c = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return test.m1(object);
}
};
tasks.add(c);
}
List<Future<Integer>> results = EXEC.invokeAll(tasks);
for (Future<Integer> fr : results) {
fr.get();
}
简短回答:当您没有性能或 IO 阻塞问题时,它就太过分了。
关于并行性能的几个因素是:
- 任务之间需要多少communication/coordination。请参阅 Embarrassingly parallel 以了解最少协调的示例。
- 并行处理的结构需要时间来创建。例如 OSX Thread takes about 90 microseconds 将被创建,因此您至少需要保存那么多(如果您创建一个)。
- 并行处理不会加速连续分数。如果任务需要一个小时,并且只有 75% 的任务可以并行处理,那么您将无法在 15 分钟内完成它。参见 Amdahl's law。
看看 Doug Lea 的 post "When to use parallel streams"。
当并行计算开始有意义时,粗略估计(在十倍内)是 100 微秒 顺序执行。尽管还有更多因素需要考虑。