float value = 0;
for (Foo foo : arrayList) {
float temporaryValue = calculate(foo);
if (temporaryValue < minValue) {
continue;
}
value = temporaryValue;
}是否可以在Java 8中更好地优化性能?例如,使用不同的迭代方法或其他方法。
发布于 2020-12-11 11:46:53
首先,简化顺序代码:
float value = 0;
for (Foo foo : arrayList) {
float temporaryValue = calculate(foo);
if (temporaryValue > minValue) {
value = temporaryValue;
}
}然后,如果ArrayList上的元素数量足够多,您可以尝试并行化代码。首先,使您的方法可并行化:
static void some_method(float[] values, int threadID, int total_threads){
float value = 0;
float minValue = Integer.MIN_VALUE;
for (int i = threadID; i < arrayList.size(); i+= total_threads) {
float temporaryValue = calculate(arrayList.get(i));
if (temporaryValue < minValue) {
continue;
}
value = temporaryValue;
}
values[threadID] = value;
}在上面的代码中,每个线程只负责从列表中的一个块(即for (int i = threadID; i < arrayList.size(); i+= total_threads))中找到最大值。最后,每个线程在值数组的对应位置(即valuesthreadID = value;)更新它找到的最大值。此更新应在结束时进行,以尽量减少潜在的错误共享开销。
现在创建线程,分配它们的工作,并等待它们完成。
int total_threads = 2;
float[] values = new float[total_threads];
List<Thread> threads = new ArrayList<>(total_threads);
for(int i = 0; i < total_threads; i++){
final int threadID = i;
threads.add(new Thread(() -> some_method(values, threadID, total_threads)));
}
threads.forEach(Thread::start);
threads.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// Calculate the maximum
float max_value = Integer.MIN_VALUE;
for (float v : values) {
max_value = Math.max(v, max_value);
}
}在每个线程执行了它们的工作并找到了它们的最大值之后,主线程将从这些值中找到其中一个最大的值:
float max_value = Integer.MIN_VALUE;
for (float v : values) {
max_value = Math.max(v, max_value);
}您可能需要进一步调优每个线程的迭代分布:
for (int i = threadID; i < arrayList.size(); i+= total_threads) 根据calculate方法的内容,使用动态循环分布可能会有好处。
发布于 2020-12-11 10:32:57
移除多余的步骤:
if(temporaryValue > value) {
value = temporaryValue;
}或者,当您有一个值break >= minValue时,只需从循环中提取。
或者使用Java 8流:
final float value = (float) arrayList
.stream()
.mapToDouble(this::calculate)
.max();这不太可能提高基本循环的性能,实际上它可能要慢一些。但是,流可以很容易地并行化(或者至少比自定义多线程容易得多)。
但是,您需要问的第一个问题是,我需要优化这段代码吗?你的名单有多大?这段代码多久被调用一次?与迭代相比,calculate()方法有多复杂?
发布于 2020-12-11 10:34:32
由于列表中满足"wins“条件的最后一个值,所以只要第一个值大于或等于min值,就可以向后迭代并脱离循环。假设计算方法没有重要的副作用。
https://stackoverflow.com/questions/65249550
复制相似问题