我试图改变一些代码,所以它可以使用多线程。当围绕代码放置一个Runnable时,我偶然发现了一个性能损失。线程内部的代码比外部线程慢?
对于澄清:原代码,让我们把它
//doSomething
了一个Runnable围绕这样的:
Runnable r = new Runnable()
{
public void run()
{
//doSomething
}
}
然后我提交了可运行的ChachedThreadPool的ExecutorService。这是我对多线程代码的第一步,以查看代码是否像原始代码一样以一个线程运行。
但是,情况并非如此。在大约2秒内执行// doSomething,Runnable执行约2.5秒。 我需要一提的是一些其他的代码,说:// doSomethingElse,里面一个Runnable 没有性能损失相比原来// doSomethingElse。
我的猜测是,// DoSomething的有一些操作在一个线程工作时不那么快,但我不知道它可能还是什么,在方面是区别//doSomethingElse。
难道是使用final int []/float []数组使Runnable慢得多吗? // doSomethingElse代码也使用了一些决赛,但// doSomething使用更多。这是我能想到的唯一的事情。
不幸的是,代码很长且不在上下文中,但我会在这里发布它。对于那些知道Mean Shift分段算法的人来说,这是代表每个像素正在计算均值漂移向量的代码的一部分。通过每个像素中的for循环
for(int i=0; i<L; i++)
运行。
timer.start(); // this is where I start the timer
// Initialize mode table used for basin of attraction
char[] modeTable = new char [L]; // (L is a class property and is about 100,000)
Arrays.fill(modeTable, (char)0);
int[] pointList = new int [L];
// Allcocate memory for yk (current vector)
double[] yk = new double [lN]; // (lN is a final int, defined earlier)
// Allocate memory for Mh (mean shift vector)
double[] Mh = new double [lN];
int idxs2 = 0; int idxd2 = 0;
for (int i = 0; i < L; i++) {
// if a mode was already assigned to this data point
// then skip this point, otherwise proceed to
// find its mode by applying mean shift...
if (modeTable[i] == 1) {
continue;
}
// initialize point list...
int pointCount = 0;
// Assign window center (window centers are
// initialized by createLattice to be the point
// data[i])
idxs2 = i*lN;
for (int j=0; j<lN; j++)
yk[j] = sdata[idxs2+j]; // (sdata is an earlier defined final float[] of about 100,000 items)
// Calculate the mean shift vector using the lattice
/*****************************************************/
// Initialize mean shift vector
for (int j = 0; j < lN; j++) {
Mh[j] = 0;
}
double wsuml = 0;
double weight;
// find bucket of yk
int cBucket1 = (int) yk[0] + 1;
int cBucket2 = (int) yk[1] + 1;
int cBucket3 = (int) (yk[2] - sMinsFinal) + 1;
int cBucket = cBucket1 + nBuck1*(cBucket2 + nBuck2*cBucket3);
for (int j=0; j<27; j++) {
idxd2 = buckets[cBucket+bucNeigh[j]]; // (buckets is a final int[] of about 75,000 items)
// list parse, crt point is cHeadList
while (idxd2>=0) {
idxs2 = lN*idxd2;
// determine if inside search window
double el = sdata[idxs2+0]-yk[0];
double diff = el*el;
el = sdata[idxs2+1]-yk[1];
diff += el*el;
//...
idxd2 = slist[idxd2]; // (slist is a final int[] of about 100,000 items)
}
}
//...
}
timer.end(); // this is where I stop the timer.
有更多的代码,但最后while循环是我第一次注意到,在性能上的差异。
任何人都可以想到为什么这段代码在Runnable内运行得比原来慢吗?
谢谢。
编辑:测量的时间是内部的代码,所以不含启动的线程的。
如果你拿一些运行260ms的东西,把它包装在一个Runnable中,并且只运行一次,那么是的,由于线程的启动开销会花费更长的时间。一次运行一些东西并不是一个很好的线程使用。请解释你为什么要运行这个多线程。 – 2010-11-15 14:34:51
我提到其他代码在Runnable内部和在外部一样快。但是的确,总的运行时间比那个长。此代码完成后,Runnable内部需要约3.5秒,而外部则需要2秒。我想以多线程的形式运行这个代码,作为应该实现的实时应用程序的一部分。巨大的for-loop(从0到L)可以分成几部分。 – RemiX 2010-11-15 14:43:21
根据您的编辑,并行代码(和测试)的外观如何? – gustafc 2010-11-15 14:55:55