ExecutorService Future ::变得非常慢 [英] ExecutorService Future::get very slow

查看:450
本文介绍了ExecutorService Future ::变得非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在并行化一个非常复杂的程序以加快速度。为此,我大部分时间都使用 ExecutorService 。到目前为止它工作得很好,但后来我注意到只有一行代码使我的程序运行速度尽可能快一半。它是 exactScore.get()的行。

I'm parallelizing a quite complex program to get it faster. For this I use most of the time the ExecutorService. Until now it worked pretty well, but then I noticed that just one line of code makes my program run half as fast as it could. It's the line with exactScore.get().

我不知道为什么,但它有时需要更多0.1秒只是为了获得Future Object的双倍值。

I don't know why, but it sometimes needs more that 0.1 s just to get the double value of the Future Object.

这是为什么?如何处理它运行得更快?有多种方法可以直接在 Double [] 中编写多线程吗?
谢谢

Why is this? How can I handle it that it runs faster? Is there a way to write directly in the Double[] while multithreading? Thanks

int processors = Runtime.getRuntime().availableProcessors();
    ExecutorService service = Executors.newFixedThreadPool(processors);

    // initialize output
    Double[] presortedExScores = new Double[sortedHeuScores.length];

    for(int i =0; i < sortedHeuScores.length; i++ ){
        final int index = i;
        final Collection<MolecularFormula> formulas_for_exact_method = multimap.get(sortedHeuScores[i]);
        for (final MolecularFormula formula : formulas_for_exact_method){
            Future<Double> exactScore = service.submit(new Callable<Double>() {
                @Override
                public Double call() throws Exception {
                    return getScore(computeTreeExactly(computeGraph(formula)));
                }
            });
            presortedExScores[index] = exactScore.get();
        }

    }


推荐答案

这是可以预料的。那不是慢;这只是它的工作。

That is to be expected. It isn't "slower" then; it is just doing its job.

来自 get()

如有必要,请等待要完成的计算,然后检索其结果。

长话短说:您似乎不理解您在代码中使用的概念。 未来的想法是,它在某些时候做某事

Long story short: it seems that you do not understand the concepts you are using in your code. The idea of a Future is that it does things at some point in the future.

通过调用 get(),你表示:我不介意等待现在直到计算结果落后于Future变得可用。

And by calling get() you express: I don't mind waiting now until the results of that computation "behind" that Future become available.

因此:你必须退后一步,再次查看你的代码;了解你的不同活动线索是如何运作的;以及他们如何/何时回到一起。

Thus: you have to step back and look into your code again; to understand how your different "threads of activity" really work; and how/when they come back together.

想到一个想法:现在,你在循环中创建Future对象;并在创建Future之后直接调用 get()。这与创建多个期货的想法完全矛盾。换句话说:而不是去:

One idea that comes to mind: right now, you you are creating your Future objects in a loop; and directly after you created the Future, you call get() on it. That completely contradicts the idea of creating multiple Futures. In other words: instead of going:

foreach X
  create future X.i
  wait/get future X.i

你可以做点什么

foreach X
  create future X.i

foreach X
  wait/get for future X.i

换句话说:让你的期货真正并行做事;而不是强制执行顺序处理。

In other words: allow your futures to really do things in parallel; instead of enforcing sequential processing.

如果这对足够没有帮助,那就说:你必须看看你的整体设计,并确定是否有办法进一步拉开的东西。现在所有的活动都密切在一起;并且惊讶:当你同时做大量的工作时,这需要时间。但正如你可能猜到的那样:这样的重新设计可能需要做很多工作;并且在不了解更多关于您的问题/代码库的情况下几乎是不可能的。

If that doesn't help "enough", then as said: you have to look at your overall design, and determine if there are ways to further "pull apart" things. Right now all activity happens "closely" together; and surprise: when you do a lot of work at the same time, that takes time. But as you might guess: such a re-design could be a lot of work; and is close to impossible without knowing more about your problem/code base.

更复杂的方法是编写代码,其中每个Future都有一种表达方式我完成了 - 然后你会只启动所有期货;并等到最后一个回来。但正如所说;我不能在这里为你设计一个完整的解决方案。

A more sophisticated approach would be that you write code where some each Future has a way of expressing "I am done" - then you would "only" start all Futures; and wait until the last one comes back. But as said; I can't design a full solution for you here.

另一个非常重要的外卖:不要盲目地使用一些发生工作的代码。编程的一个要素是理解源代码中使用的每个和任何概念。你应该非常清楚你的代码在之前运行它并找到哦,那个 get()让事情变得缓慢。

The other really important take-away here: don't just blindly use some code that "happens" to work. One essence of programming is to understand each and any concept used in your source code. You should have a pretty good idea what your code is doing before running it and finding "oh, that get() makes things slow".

这篇关于ExecutorService Future ::变得非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆