我想知道为什么在JavaCV中访问普通数组和CvMat的元素时处理时间差异很大。指示性地,当在我的计算机上运行以下代码时,普通Java阵列需要0.8秒,而CvMat需要超过26秒(!)。访问CvMat的任何想法都是如此之慢?
// Declare a normal java array and a CvMat (requires JavaCV)
double ArrayJava[][] = new double[10000][10000];
CvMat ArrayJavaCV = CvMat.create(10000, 10000,CV_32F);
// Get current time
long startTime1 = System.currentTimeMillis();
// For each element, initialize with a value, get the value and increase it by 0.1 and put it back
for(int i=0; i<ArrayJava.length; i++){
for (int j =0; j<ArrayJava[1].length; j++){
ArrayJava[i][j] = i;
double val1 = ArrayJava[i][j] + 0.1;
ArrayJava[i][j] = val1;
}
}
// Compute processing time
long endTime1 = System.currentTimeMillis();
System.out.println("ArrayJava processing time: "+(endTime1 - startTime1)/1000.+" sec");
// Perform the same procedure for the CvMat
long startTime2 = System.currentTimeMillis();
for(int i=0; i<ArrayJavaCV.rows(); i++){
for (int j =0; j<ArrayJavaCV.cols(); j++){
ArrayJavaCV.put(i, j, i);
double val2 = ArrayJavaCV.get(i, j) + 0.1;
ArrayJavaCV.put(i, j, val2);
}
}
long endTime2 = System.currentTimeMillis();
System.out.println("ArrayJavaCV processing time: "+(endTime2 - startTime2)/1000.+" sec");
答案 0 :(得分:0)
在像C ++这样的本地语言中,使用getter(i = getCount())而不是直接访问字段(i = mCount)是常见做法。这是C ++的一个很好的习惯,并且经常用于其他面向对象的语言,如C#和Java,因为编译器通常可以内联访问,如果您需要限制或调试字段访问,您可以随时添加代码。 / p>
然而,这对Java来说是一个坏主意。虚拟方法调用比实例字段查找要昂贵得多。遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的,但在类中,您应该始终直接访问字段。
没有JIT,直接字段访问速度比调用一个简单的getter快约3倍。使用JIT(直接字段访问与访问本地一样便宜),直接字段访问比调用一个简单的getter快约7倍。