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

时间:2014-05-15 11:29:42

标签: java opencv javacv

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

1 个答案:

答案 0 :(得分:0)

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

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

没有JIT,直接字段访问速度比调用一个简单的getter快约3倍。使用JIT(直接字段访问与访问本地一样便宜),直接字段访问比调用一个简单的getter快约7倍。