为什么在JavaCV中访问CvMat的元素如此缓慢?



我想知道为什么在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");   

在像c++这样的本地语言中,通常的做法是使用getter (i = getCount())而不是直接访问字段(i = mCount)。对于c++来说,这是一个很好的习惯,在c#和Java等其他面向对象语言中也经常这样做,因为编译器通常可以内联访问,如果你需要限制或调试字段访问,你可以随时添加代码。

然而,这在Java上是一个坏主意。虚拟方法调用的开销比实例字段查找要大得多。遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的,但在类中应该始终直接访问字段。

如果没有JIT,直接访问字段比调用简单的getter快3倍。使用JIT(直接字段访问和访问本地一样便宜),直接字段访问比调用普通的getter要快7倍。

相关内容

  • 没有找到相关文章

最新更新