You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNI原生函数为何始终返回0耗时?Android开发技术求助

问题原因

你的代码返回0是因为编译器死代码消除优化:由于arr1和matrix1在创建后没有被任何实际操作使用(除了创建),编译器会判定这些代码是“无用的”,直接跳过执行,导致begin和end的时间差几乎为0,最终返回0。而当你加入matrix1(1,1)时,编译器认为这个对象被使用了,才会执行创建数组和矩阵的代码。

解决方案

无需修改返回值,只需让编译器认为arr1和matrix1是被使用的,以下是几种可行方法:

方法1:强制读取变量/对象(推荐)

在创建matrix1后,添加一行强制读取对象的代码,编译器就不会优化掉相关创建逻辑:

JNIEXPORT jint JNICALL Java_com_app_Native_test(JNIEnv *env, jobject object)
{
   steady_clock::time_point begin = steady_clock::now();
   int lenght = 500000000;
   int * arr1 = new int[lenght];
   for(int i = 0; i < lenght; i++)
   {
       *(arr1+i) = i+1;
   }
   matrix<int, 100> matrix1(arr1, lenght);
   // 强制读取matrix1,阻止编译器优化
   (void)matrix1(1, 1);
   steady_clock::time_point end = steady_clock::now();
   return duration_cast<microseconds>(end-begin).count();
}

(void)是告诉编译器我们故意忽略返回值,避免未使用变量的警告。

方法2:使用空函数“消耗”变量

定义一个空函数,将arr1和matrix1作为参数传入,编译器会认为这些变量被使用:

// 定义在函数外或者头文件中
void preventOptimization(const void*) {}

JNIEXPORT jint JNICALL Java_com_app_Native_test(JNIEnv *env, jobject object)
{
   steady_clock::time_point begin = steady_clock::now();
   int lenght = 500000000;
   int * arr1 = new int[lenght];
   for(int i = 0; i < lenght; i++)
   {
       *(arr1+i) = i+1;
   }
   matrix<int, 100> matrix1(arr1, lenght);
   // 传入变量,阻止优化
   preventOptimization(arr1);
   preventOptimization(&matrix1);
   steady_clock::time_point end = steady_clock::now();
   return duration_cast<microseconds>(end-begin).count();
}

注意不要把这个空函数定义成内联函数,否则编译器可能还是会优化掉。

方法3:局部禁用编译器优化

如果上面的方法无效,可以用编译器指令临时关闭当前代码块的优化(以GCC/Clang为例):

JNIEXPORT jint JNICALL Java_com_app_Native_test(JNIEnv *env, jobject object)
{
   steady_clock::time_point begin = steady_clock::now();
   // 临时关闭优化
   #pragma GCC push_options
   #pragma GCC optimize ("O0")
   int lenght = 500000000;
   int * arr1 = new int[lenght];
   for(int i = 0; i < lenght; i++)
   {
       *(arr1+i) = i+1;
   }
   matrix<int, 100> matrix1(arr1, lenght);
   // 恢复之前的优化级别
   #pragma GCC pop_options
   steady_clock::time_point end = steady_clock::now();
   return duration_cast<microseconds>(end-begin).count();
}

这种方法会影响代码块的执行效率,仅在其他方法无效时使用。

内容的提问来源于stack exchange,提问作者NEKKITIS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:42:54