是否值得线程完成需要1秒钟的操作?

时间:2011-02-22 10:16:52

标签: java multithreading performance

我想提高我的应用程序的性能,并发现它花费了大约90%的应用程序 运行时间做我的while循环之一。我在这个while循环中基本上做的是以下内容。

int i = 0;
while (i < 100)
  1) Search a big arrayList for position of an objects timestamp.
  2) Search the same arrayList for position of another objects timestamp.
  3) I get this subArrayList (or timewindow).
  4) The array that now is returned I iterate through and compute an average.
  5) I push this average into a stack.
  i++
endwhile

此循环的一次迭代平均需要1-10毫秒,而这通常是整个部分 需要100-1000毫秒。根据我的理解,即使第99个子列表只需要大约1毫秒来完成,它也会 在它有机会做到这一点之前已经等了99-9999毫秒,对,或者我离开这里了?

我想到的是产生一个线程并让它在位置i上返回它的值。当所有线程完成后,继续编程。

我不关心时间窗x的平均值是否在时间窗y的平均值之前返回,只是在继续之前所有线程/值都已返回。

我收到了以下问题:

尝试使每个迭代成为某种类型的线程并并行计算它是否值得?

如果是这样,我是否需要一个线程池,这样做的最佳方法是什么?

6 个答案:

答案 0 :(得分:4)

线程的问题是......它是一个重要的对象来启动和同步。因此,一秒钟的操作可能不值得。

看一下Actor模型模式。对于Java,您可以使用Akka。使用actor,您可以轻松地进行并发操作。

答案 1 :(得分:3)

  

我从一个大阵列获得子列表。

为什么你不能使用相同的数组来计算平均值。你知道索引的开始和结束位置。在父级内运行另一个while循环,同时计算平均值。

  

如果你选择穿线,我有   以下问题。

要并行运行的块的哪个部分

同步怎么样? ,multliple线程写入堆栈。

答案 2 :(得分:1)

协调线程有很大的开销, 除非它们允许多个内核启动,或者你可以将计算与I / O重叠,否则它们根本无法提供性能。

在考虑改变设计之前,为什么不找出你遇到的瓶颈并修复它们? Here's a simple way to do that. 通常你可以通过这种方式找到大的加速。

答案 3 :(得分:0)

如何从大阵列中获取子列表?一个简单的,已经有效的改进是只迭代数组一次,选择元素并将它们添加到迭代计算的平均值。

类似的东西:

int sum = 0;
int count = 0;
for(MyObject object : myBigArray){
    if (mustBelongToSublist(object){
        count++;
        sum += object.value();
    }
}
int average = (double)sum/count;

答案 4 :(得分:0)

取决于你的目标。应该在不到一秒的时间内运行吗?数据可能会增长(很多)吗?

仅当您可以有效地创建子任务时,线程才适用。例如,如果您迭代的列表将是链接列表,则它可能不适用于每个元素的廉价计算,因为对于子任务,导航到列表的子部分是昂贵的。如果你有单独的列表,你每个都必须迭代它可能只是好,因为你将开始从列表的开头迭代。

在你的情况下,当然。为什么不。您必须决定如何处理结果的策略。它们应该放在你的堆栈中吗?或者没关系?你想要线程,然后让线程等到前面的那些完成?或者你使用不同的策略?等待线程不好,但是。如果你可以创建2个或4个线程,并且每个线程都可以继续工作,那就是它变得非常高效。

当你将i从0迭代到100并且每次迭代不依赖于另一次迭代时,你很好将它们分成子任务。你有100个任务。这些可以分成线程。

不要过度使用线程,只有有限的CPU数量和100个任务,所以2或4个线程就足够了。制作主题并告诉他们为索引计算你的内容,例如25至50岁。

答案 5 :(得分:0)

我喜欢@Suesh和@nanda的回答gven,并想总结一下。

首先,优化您的代码。我认为至少有一半的时间用于复制子数组。您必须在适当的位置工作:找到数组的第一个和最后一个索引并计算元素的平均值。最好的解决方案只需要在阵列上运行一次。如果不可能(我不知道你的逻辑是什么,找到索引)在更糟糕的情况下你必须迭代数组两次。但不要复制其内容。

如果这个优化没有足够的帮助来考虑使用Akka的线程池或actor模型(正如nanda建议的那样)