代码之家  ›  专栏  ›  技术社区  ›  Ford O.

是什么让JNI对象分配如此缓慢?

  •  0
  • Ford O.  · 技术社区  · 4 年前

    我对一段代码进行了基准测试,该代码使用

    1. env->NewObject
    2. env->AllocObject , env->SetLongField

    令我惊讶的是,代码的执行时间分别为250毫秒和125毫秒。这比同等的java程序要慢10-5倍!

    JNI调用的开销也比本文中提到的要大一个数量级 What makes JNI calls slow? (方向相反) java -> Native ).

    是什么让它这么慢?C难道不能直接访问Java堆吗?

    或者,有没有更有效的方法通过JNI将数据从C传递到java?

    java代码:

    public class Main { 
       static {
          System.loadLibrary("main"); 
       }
     
       private native void bench();
    
       static void bench_java() {
          long now = System.currentTimeMillis();
          for (int i=0; i < 1000000; i++) new Number(i);
          System.out.println(System.currentTimeMillis() - now); 
       }
    
       public static void main(String[] args) {
          new Main().bench(); 
       }
    }
    
    public class Number {
       long j;
    
       public Number(long j) {
          this.j = j;
       }
    }
    

    c代码:

    #include "jni.h"  
    #include <stdio.h>   
    #include <sys/time.h>
    
     
    
    JNIEXPORT void JNICALL Java_Main_bench(JNIEnv *env, jobject thisObj) {
       struct timespec start, end;
    
       jclass    cls  = (*env)->FindClass(env, "Number");
       jmethodID init = (*env)->GetMethodID(env, cls, "<init>", "(J)V");
    
       clock_gettime(CLOCK_MONOTONIC, &start);
       for (int i=0; i<1000000; i++) (*env)->NewObject(env, cls, init, 0);
       clock_gettime(CLOCK_MONOTONIC, &end);
    
       printf("Time elapsed %lu ms\n", (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000);
       return;
    }
    
    0 回复  |  直到 4 年前