有没有谁可以解释一下为什么鸿蒙的IPC性能不及安卓的一半?
mb6194ba7320111
发布于 2021-11-23 10:00
浏览
1收藏
鸿蒙官宣的IPC性能相当强悍,吊打QNX,于是萌生想法,看一下在android上面,鸿蒙到底会比android的ipc强多少?
于是根据官方IDL示例文档(IDL)撸了一段最简单的ipc调用,就是透传一个32位int整数,拿回来之后加一,在ipc调用透传,循环一万次,最终看下时间,关键代码如下:
public class MainAbilitySlice extends AbilitySlice {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "MainAbilitySlice");
public MyIdlInterfaceProxy proxy;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Button button = (Button) findComponentById(ResourceTable.Id_button_Login);
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.HIGH);
Revocable revocable = globalTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, "async task1 run");
if (proxy != null) {
int sum = 0;
long t1 = System.currentTimeMillis();
try {
while (sum < 10000) {
sum = proxy.demoFun(++sum);
System.out.println("sum = " + sum);
}
} catch (RemoteException e) {
e.printStackTrace();
}
long t2 = System.currentTimeMillis();
System.out.println("time = " + (t2 - t1));
}
}
});
HiLog.info(LABEL_LOG, "after async task1");
}
});
connectServer();
}
private IAbilityConnection conn = new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName element, IRemoteObject remote, int resultCode) {
proxy = new MyIdlInterfaceProxy(remote);
HiLog.debug(LABEL_LOG, "onAbilityConnectDone");
}
@Override
public void onAbilityDisconnectDone(ElementName element, int resultCode) {
proxy = null;
System.out.println("------resultCode = " + resultCode);
}
};
private void connectServer() {
Intent intent = new Intent();
ElementName elementName = new ElementName(
"",
"com.example.idldemo",
"com.example.idldemo.ServiceAbility");
intent.setElement(elementName);
connectAbility(intent, conn);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
同理,在android的应用中使用AIDL方式进行相同的操作,相关代码如下:
public class MainActivity extends AppCompatActivity {
private static String TAG = MainActivity.class.getSimpleName();
public IMyAidlInterface binder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindSvr();
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (binder != null) {
long t1 = System.currentTimeMillis();
int sumTmp = 0;
while (sumTmp < 10000) {
sumTmp = binder.funSum(++sumTmp);
Log.d(TAG, "sum = " + sumTmp);
}
long t2 = System.currentTimeMillis();
Log.d(TAG, "time = " + (t2 - t1));
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void bindSvr() {
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
binder = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected svr name " + name);
}
};
Intent intent = new Intent();
intent.setPackage("cn.example.aidldemo");
intent.setAction("cn.example.aidldemo.server");
bindService(intent, connection, Service.BIND_AUTO_CREATE);
}
}
服务端的方法实现就是一个透传值:
@Override
public int demoFun(int _anInt) throws RemoteException {
return _anInt;
}
测试环境为:
华为Mate30(TAS-AL00)
HarmoneyOS 2.0.0
都是debug包
运行10次取平均值(ms):
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | avg | |
---|---|---|---|---|---|---|---|---|---|---|---|
android | 969 | 901 | 888 | 898 | 920 | 905 | 968 | 913 | 968 | 714 | 904.4 |
harmoney | 2440 | 2738 | 2795 | 2717 | 2776 | 2636 | 2241 | 2016 | 2260 | 2294 | 2491.3 |
[问号脸][wtf]
究竟为何呢?颠覆认知了啊? 这么打脸么?
是不是我哪里做的不对?
鸿蒙的普通binder和dbinder到底都是个什么鬼?
反正,希望高人指点一下吧,帮我解解惑,感谢!
分类
标签
已于2021-11-23 10:06:53修改
赞
3
收藏 1
回复
相关推荐
要回答你这个问题,首先我们要搞明白什么是IPC,IPC Inter Process Communication,是操作系统内核最为重要的三个基础功能之一,其他两个分别是调度和内存管理。IPC有很多种类,包括如各种各样的锁,信号灯,消息队列,事件,signal,共享内存等等,IPC的作用是用于进程与进程之间的消息互通,并基于这些消息互通实现一些同步、互斥、协同等工作。
从这个定义我们可以看出,IPC不止一种,在华为官方的宣传当中,应该是指某种特定的IPC,鉴于他在跟QNX对比,那么应该对比的是微内核所使用的,操作系统组件之间的IPC,QNX是典型的微内核操作系统,对于微内核操作系统而言,因为各个操作系统组件位与不同的进程空间,那么IPC的使用是非常频繁的,所以IPC的效率直接决定了微内核操作系统的效率,也正是如此,华为官方宣传鸿蒙的微内核的时候,才会跟QNX进行对比。
我们再说回来,说你的测试内容本身,你的测试其实源于安卓的特有IPC手段binder,可能令你意外的是,其实HarmonyOS也是利用的安卓的binder作为系统服务和应用框架的主要IPC手段的。binder在安卓中得到了巨大的成功,也被Linux社区所接纳,现在是Linux的内置IPC手段之一了,binder最大的技术贡献是单次拷贝。这里顺带说一下,Linux是宏内核,IPC不影响内核本身的效率,但是应用层的效率也很重要。
其实你的测试无法得出IPC的差异结论的,因为不论你在华为手机上还是其他安卓手机上,用的都是binder。至于你实测的数据差异,我想可能是框架层造成的,在IDL的调用方式上,安卓框架直接对接binder,而HarmonyOS框架可能还要进行一层额外的Java层到HarmonyOS框架层的封装。当然这只是猜测,因为HarmonyOS没有开源,我也无从得知。
HarmonyOS还有一个dbinder,其实这个机制只是把IPC扩展为RPC的一个东西,本质上也与IPC本身的效率没关系。
我觉得你的测试数据还是有意义的,华为的团队应该重视这其中的效率差异,尽量减少在L3-L5双框架环境中的应用效率差异,这个是可以做到的,也是应该做到的。
在跑demo的时候日志里面打印了一句具体没有记录,大概意思就是这个通信不是dbinder,是普通的binder,就按照普通binder去通信,所以留意到了这一点,那么说来还是有一个调度判断,是否去走软总线RPC,还是本地的IPC,IDL里面也并没有参数来设置,Harmoney可能比较自信调度吧,或者为了API的易用性,总之是结果感人了,还是希望能够招来官方给个解释,比较安心