NDK开发性能提升

初步了解以下NDK开发对性能的提升,包括dex2oat的处理、函数运行在解释模式、ART模式、JNI模式的性能差别,以及数据类型的转换。
NDK开发的优缺点


什么是ART模式
dex2oat虽然提升了性能,但是对手机的存储空间、性能、耗电量提出了更高的要求(因为要把几乎所有的函数都要编译一遍),所以从Android7.0开始换为了ART的运作方式

所以java函数在Android7.0之后可能运行在三种模式下:

OAT文件分析
Google提供了一个[oatdump](oatdump/oatdump.cc - platform/art - Git at Google (googlesource.com) )工具来反编译oat文件
新建一个native C++项目来测试对oat文件反编译,分析文件结构
在MainActivity.java中写一个简单函数编译一下,安装到手机上
这里测试项目的SDK最好使用Android5.0以下的不然编译出来的dex太多找起来麻烦
public int java_add(int num){
int k = 0;
for (int i = 0; i < num; i++) {
k += i;
}
return k;
}

找到生成的odex以及vdex文件
.vdex
:其中包含 APK 的未压缩 DEX 代码,以及一些旨在加快验证速度的元数据。.odex
:其中包含 APK 中已经过 AOT 编译的方法代码。将这两个文件拷贝到
sdcard/
目录下,然后pull下来

- vdex有自己的文件头,在后面也有原本dex的文件头
删除vdex的文件头之后,就可以直接用dex的模板来解析dex 文件

- 将删除vdex文件头的文件复制一份为dex文件
cp .\base.vdex base.dex
用GDA可以打开(jadx打开失败)

- 解析后可以看到我们之前写的
java_add
接下来再看一下odex
使用系统自带的oatdump工具反编译一下odex文件,顺便将其pull下来查看一下
atdump --oat-file=base.odex >>/sdcard/oatdump01.txt

- 从结果可以看到
oatdump
成功的将oat文件反编译为了smail指令 - 汇编代码没有生成是因为Android7.0之后的ART不会直接把所有函数都执行dex2oat,它会在运行一段时间之后才会编译为汇编代码。
简单测试一下函数的ART模式下和JNI模式下的运行速度差别有多大
int k = 0;
for (int i = 0; i < num; i++) {
k += i;
}
return k;

- 从运行一百万次的结果来看其实差别不是很大,表明java函数在执行了一定次数后迅速的从解释模式切换到了ART模式
Java&Native数据类型对比
Java中有8种基本数据类型:

引用数据类型:

数组引用类型:

接下来写一些demo来测试类型处理

String和jstring的交换
String resultString = testjstringapis("Hello from java");
Log.i("xiaoeryu", "result: " + resultString);
extern "C"
JNIEXPORT jstring JNICALL
Java_com_xiaoeryu_performancetest01_MainActivity_testjstringapis(JNIEnv *env, jobject thiz,
jstring content) {
// TODO: implement testjstringapis()
const char* a = env->GetStringUTFChars(content, nullptr);
jint jstring_size = env->GetStringUTFLength(content);
if (a != nullptr){
__android_log_print(ANDROID_LOG_INFO, "testjstring", "char content: %s, size: %d", a, jstring_size);
}
jstring result = env->NewStringUTF("Hello from jni");
return result;
}
result

- 标题: NDK开发性能提升
- 作者: xiaoeryu
- 创建于 : 2023-10-06 12:05:11
- 更新于 : 2023-10-06 12:26:59
- 链接: https://github.com/xiaoeryu/2023/10/06/NDK开发性能提升/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。