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

为什么在JavaCV中访问CvMat的元素如此缓慢?,java,opencv,javacv,Java,Opencv,Javacv,我想知道为什么在JavaCV中访问普通数组和CvMat的元素时,处理时间会有如此大的差异。作为指示,在我的计算机上运行以下代码时,普通Java数组需要0.8秒,超过26秒!对于CvMat。你知道为什么访问CvMat这么慢吗 // Declare a normal java array and a CvMat (requires JavaCV) double ArrayJava[][] = new double[10000][10000]; CvMat ArrayJavaCV = CvMat.c

我想知道为什么在JavaCV中访问普通数组和CvMat的元素时,处理时间会有如此大的差异。作为指示,在我的计算机上运行以下代码时,普通Java数组需要0.8秒,超过26秒!对于CvMat。你知道为什么访问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++等本地语言中,使用GETSt:I= GETCOUNT而不是直接访问字段i= McUT是常见的做法。这是一个极好的C++习惯,而且经常在其他面向对象语言中如C和java实现,因为编译器通常可以内联访问,如果需要限制或调试字段访问,则可以随时添加代码。 然而,这在Java上是一个坏主意。虚拟方法调用的开销比实例字段查找要大得多。遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的,但是在类中,您应该始终直接访问字段


如果没有JIT,直接字段访问比调用一个微不足道的getter快3倍左右。在JIT中,直接字段访问和访问本地字段一样便宜,直接字段访问比调用一个微不足道的getter快7倍左右。

每次调用put或get时,这是一个java成员函数调用,它反过来调用一个C包装函数,它再次调用了一个C opencv库函数。如果您遵循Java约定并用小写字母命名本地变量,代码的可读性会更好。例如:CvMat arrayJavaCV=。。。