首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这样做最有效的方法是什么?

这样做最有效的方法是什么?
EN

Stack Overflow用户
提问于 2020-12-11 10:25:33
回答 3查看 108关注 0票数 1
代码语言:javascript
复制
float value = 0;
for (Foo foo : arrayList) {
    float temporaryValue = calculate(foo);
    if (temporaryValue < minValue) {
        continue;
    }   
    value = temporaryValue;
}

是否可以在Java 8中更好地优化性能?例如,使用不同的迭代方法或其他方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-12-11 11:46:53

首先,简化顺序代码:

代码语言:javascript
复制
float value = 0;
for (Foo foo : arrayList) {
    float temporaryValue = calculate(foo);
    if (temporaryValue > minValue) {
        value = temporaryValue;
    }  
}

然后,如果ArrayList上的元素数量足够多,您可以尝试并行化代码。首先,使您的方法可并行化:

代码语言:javascript
复制
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;)更新它找到的最大值。此更新应在结束时进行,以尽量减少潜在的错误共享开销。

现在创建线程,分配它们的工作,并等待它们完成。

代码语言:javascript
复制
    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);
    }
}

在每个线程执行了它们的工作并找到了它们的最大值之后,主线程将从这些值中找到其中一个最大的值:

代码语言:javascript
复制
float max_value = Integer.MIN_VALUE;
for (float v : values) {
    max_value = Math.max(v, max_value);
}

您可能需要进一步调优每个线程的迭代分布:

代码语言:javascript
复制
 for (int i  = threadID; i < arrayList.size(); i+= total_threads) 

根据calculate方法的内容,使用动态循环分布可能会有好处。

票数 2
EN

Stack Overflow用户

发布于 2020-12-11 10:32:57

移除多余的步骤:

代码语言:javascript
复制
if(temporaryValue > value) {
    value = temporaryValue;
}

或者,当您有一个值break >= minValue时,只需从循环中提取。

或者使用Java 8流:

代码语言:javascript
复制
final float value = (float) arrayList
    .stream()
    .mapToDouble(this::calculate)
    .max();

这不太可能提高基本循环的性能,实际上它可能要慢一些。但是,流可以很容易地并行化(或者至少比自定义多线程容易得多)。

但是,您需要问的第一个问题是,我需要优化这段代码吗?你的名单有多大?这段代码多久被调用一次?与迭代相比,calculate()方法有多复杂?

票数 1
EN

Stack Overflow用户

发布于 2020-12-11 10:34:32

由于列表中满足"wins“条件的最后一个值,所以只要第一个值大于或等于min值,就可以向后迭代并脱离循环。假设计算方法没有重要的副作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65249550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档