java是否值得线程化一个需要1秒才能完成的操作?
我想提高我的应用程序的性能,发现它花费了大约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上返回它的值。当所有线程都完成时,继续程序
我不在乎timewindow x的平均值是否比timewindow y的平均值早返回,只在乎在我继续之前所有线程/值都已返回
我有以下问题:
让每次迭代都成为某种线程并并行计算是否值得
如果是这样,我是否需要一个线程池,最好的方法是什么
# 1 楼答案
这取决于你的目标。它应该在一秒钟内运行吗?数据可能会增长(很多)
只有在能够高效地创建子任务时,线程才适用。例如,如果你迭代的列表是一个链表,它可能不适用于每个元素的廉价计算,因为对于一个子任务,导航到列表的子部分是昂贵的。如果你有单独的列表,每个列表都需要迭代,这可能很好,因为你将从列表的开头开始迭代
对你来说,当然。为什么不呢?不过,你必须决定如何处理结果的策略。它们应该按顺序放在你的书堆里吗?还是无关紧要?你想先穿线,然后让线等前面的人穿完吗?还是你使用了不同的策略?不过,ofc表示,等待线程并不好。如果你能创建2到4个线程,并且每个线程都能持续工作,那么它就会变得非常高效
当你将i从0迭代到100,并且每次迭代都不依赖于另一次迭代时,你最好将它们分成子任务。你有100项任务。这些可以在线程之间拆分
不要过度使用线程,你只有有限的CPU和100个任务,所以2到4个线程就足够了。制作线程,并告诉他们计算你的while的内容,例如25到50
# 2 楼答案
如何从大数组中获取子列表?一个简单而有效的改进是只对数组进行一次迭代,选择元素并将其添加到迭代计算的平均值中
比如:
# 3 楼答案
协调线程的开销很大, 除非它们允许多个内核启动,或者如果您可以将计算与I/O重叠,否则它们对性能没有任何帮助
在考虑设计变更之前,为什么不找出你的瓶颈并加以解决呢Here's a simple way to do that. 通常你可以通过这种方式找到大的加速
# 4 楼答案
为什么不能用同一个数组来计算平均值呢。你知道索引的开始和结束位置。在父级while中运行另一个while循环以计算平均值
你想在街区的哪个部分并行运行
同步呢,多线程写入堆栈
# 5 楼答案
我喜欢@Suesh和@nanda的回答,并想总结一下
首先,优化你的代码。我认为,至少有一半的操作时间用于复制子阵列。你必须在适当的地方工作:找到数组的第一个和最后一个索引,并计算元素的平均值。最好的解决方案只需要在阵列上运行一次。如果在更糟糕的情况下不可能(我不知道找到索引的逻辑是什么),则必须迭代数组两次。但不要复制它的内容
如果这种优化没有足够的帮助,请考虑使用Akka的线程池或参与者模型(正如nanda所建议的)
# 6 楼答案
线程的问题是。。。这是一个需要启动和同步的沉重任务。所以一秒钟的手术可能不值得
看看演员模型模式。对于Java,可以使用Akka。使用actor,您可以轻松地执行并发操作