android 下Protobuff框架性能测试结果
android 下Protobuff常用的框架有三个: protobuff自身, square出的wire , protostuff
由于protobuff会为每个属性生成大量不常用的方法,当程序比较复杂时容易超过android的60K个方法的上限, 所以本次测试未包括protobuff
测试逻辑是循环100次序列化100个元素的数组,并反序列化,求平均值,代码如下:
wire的测试代码:
public void onClickButton(View view){
if (TestTask.isCancel){
TestTask.isCancel = false;
TestTask.sumDeserializeTime = 0;
TestTask.sumTime = 0;
TestTask.runCount = 0;
TextView text1 = (TextView) findViewById(R.id.textView2);
text1.setText("");
new TestTask( (TextView) findViewById(R.id.textView2)
, (TextView) findViewById(R.id.button1)).execute();
((TextView)view).setText("测试中,点击中断");
}else{
((TextView)view).setText("正在中断...");
TestTask.isCancel = true;
}
}
static class TestTask extends AsyncTask<Void,Void,Long>{
long serializeTime=0;
long deserializeTime=0;
static long sumTime=0;
static long sumDeserializeTime=0;
static int runCount=0;
static boolean isCancel=true;
TextView text1;
TextView btn;
public TestTask(TextView text1,TextView btn) {
this.text1 = text1;
this.btn = btn;
}
@Override
protected Long doInBackground(Void... params) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
List<ListItem> itemList = new ArrayList<ListItem>();
ListItem.Builder itemBuilder = new ListItem.Builder();
ListItem item;
for (int j = 0; j < 100; j++) {
item = itemBuilder.title("test Title"+i+":"+j)
.remark("test Remark"+i+":"+j)
.coverUrl("http://pic.ozreader.com/abc.pic")
.uri("PKB:TESTURI")
.build();
itemList.add(item);
}
ScrollList.Builder listBuilder= new ScrollList.Builder();
ScrollList list = listBuilder.haveMore(false).tags(itemList).build();
byte[] dataBuffer = list.toByteArray();
serializeTime = System.currentTimeMillis()-startTime;
Wire wire = new Wire();
try {
ScrollList resultList = wire.parseFrom(dataBuffer, ScrollList.class);
if (resultList == null){
Log.e("TEST", "resultList is null");
break;
}else if (resultList.tags == null){
Log.e("TEST", "resultList.tags is null");
break;
}else if (resultList.tags.size() <= 0){
Log.e("TEST", "resultList.tags is empty");
break;
}else if (resultList.tags.size() != 100){
Log.e("TEST", "resultList.tags is wrong");
break;
}else if (!resultList.tags.get(0).uri.equals("PKB:TESTURI")){
Log.e("TEST", "resultList.tags content is wrong");
break;
}
deserializeTime = System.currentTimeMillis()-startTime-serializeTime;
} catch (IOException e) {
e.printStackTrace();
}
}
return System.currentTimeMillis() - startTime;
}
@Override
protected void onPostExecute(Long result) {
sumTime += result;
sumDeserializeTime += deserializeTime;
runCount ++;
text1.append("result:"+result+", serializeTime:"+serializeTime+", deserializeTime:"+deserializeTime+", runCount:"+runCount+", avg:"+sumTime/runCount+", avg deserializeTime:"+sumDeserializeTime/runCount+"\n");
if (isCancel){
text1.append("测试中断.");
btn.setText("开始测试");
}else if (runCount < 100){
new TestTask(text1,btn).execute();
}else{
isCancel = true;
text1.append("测试完成.");
btn.setText("开始测试");
}
}
}
protobuff的测试代码:
public void onClickButton(View view){
if (TestTask.isCancel){
TestTask.isCancel = false;
TestTask.sumDeserializeTime = 0;
TestTask.sumTime = 0;
TestTask.runCount = 0;
TextView text1 = (TextView) findViewById(R.id.textView2);
text1.setText("");
new TestTask( (TextView) findViewById(R.id.textView2)
, (TextView) findViewById(R.id.button1)).execute();
((TextView)view).setText("测试中,点击中断");
}else{
((TextView)view).setText("正在中断...");
TestTask.isCancel = true;
}
}
static class TestTask extends AsyncTask<Void,Void,Long>{
long serializeTime=0;
long deserializeTime=0;
static long sumTime=0;
static long sumDeserializeTime=0;
static int runCount=0;
static boolean isCancel=true;
TextView text1;
TextView btn;
public TestTask(TextView text1,TextView btn) {
this.text1 = text1;
this.btn = btn;
}
@Override
protected Long doInBackground(Void... params) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
List<ListItem> itemList = new ArrayList<ListItem>();
ScrollList list = new ScrollList();
list.setHaveMore(false);
list.setTagsList(itemList);
ListItem item;
for (int j = 0; j < 100; j++) {
item = new ListItem();
item.setTitle("test Title"+i+":"+j);
item.setRemark("test Remark"+i+":"+j);
item.setCoverUrl("http://pic.ozreader.com/abc.pic");
item.setUri("PKB:TESTURI");
itemList.add(item);
}
LinkedBuffer buffer = LinkedBuffer.allocate(1024);
byte[] dataBuffer = ProtobufIOUtil.toByteArray(list, ScrollList.getSchema(), buffer);
serializeTime = System.currentTimeMillis()-startTime;
ScrollList resultList = new ScrollList();
ProtobufIOUtil.mergeFrom(dataBuffer, resultList, ScrollList.getSchema());
if (resultList.getTagsList() == null){
Log.e("TEST", "resultList.tags is null");
break;
}else if (resultList.getTagsList().size() <= 0){
Log.e("TEST", "resultList.tags is empty");
break;
}else if (resultList.getTagsList().size() != 100){
Log.e("TEST", "resultList.tags is wrong");
break;
}else if (!resultList.getTagsList().get(0).getUri().equals("PKB:TESTURI")){
Log.e("TEST", "resultList.tags content is wrong");
break;
}
deserializeTime = System.currentTimeMillis()-startTime-serializeTime;
}
return System.currentTimeMillis() - startTime;
}
@Override
protected void onPostExecute(Long result) {
sumTime += result;
sumDeserializeTime += deserializeTime;
runCount ++;
text1.append("result:"+result+", serializeTime:"+serializeTime+", deserializeTime:"+deserializeTime+", runCount:"+runCount+", avg:"+sumTime/runCount+", avg deserializeTime:"+sumDeserializeTime/runCount+"\n");
if (isCancel){
text1.append("测试中断.");
btn.setText("开始测试");
}else if (runCount < 100){
new TestTask(text1,btn).execute();
}else{
isCancel = true;
text1.append("测试完成.");
btn.setText("开始测试");
}
}
}
测试结果为(单位豪秒):
手机环境:魅族MX2
1) wire 1.5.1 ,网址 https://github.com/square/wire
avg: 1860~1907 , 最小值约为1500左右,极少出现, 全过程随机分布
avg deserializeTime: 9~10, 最小值约为5,极少出现,全过程随机分布
2) protostuff 1.0.8 ,网址 https://code.google.com/p/protostuff/
avg: 1100~1150,非常稳定 , 最小值约为450左右,主要集中在前几次循环,循环10次后就稳定在11XX左右,偶有600~800的情况,多次重复测试情况基本一致,观察自动GC并无内存泄漏的问题, 暂时不确定速度变化的原因.
avg deserializeTime: 6, 最小值约为3,极少出现,主要集中在刚开始,绝大多数为5,偶有达到16的情况.
分析: wire的性能明显比不上protostuff, 速度也不太稳定,起落较大. 考虑到protostuff的开发模式是普通的pojo方式,比较方便,不像protobuff和wire的builder方式,超麻烦. 所以最终推荐不是逻辑超复杂的企业app都使用protostuff .
android 下Protobuff框架性能测试结果的更多相关文章
- Android/Linux下CGroup框架分析及其使用
1 cgroup介绍 CGroup是control group的简称,它为Linux kernel提供一种任务聚集和划分的机制,可以限制.记录.隔离进程组(process groups)所使用的资源( ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
- Android 下的usb框架及功能点【转】
本文转载自:https://blog.csdn.net/tianruxishui/article/details/37902959 有关USB android框架的链接 http://blog.sin ...
- [Android]Android端ORM框架——RapidORM(v2.0)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5626716.html [Android]Android端ORM ...
- Android开源测试框架学习
近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料. Android测试大致分三大块: 代码层测试 用户操作模拟,功能测试 安装部署及稳定性测试 代码层测试 对于一般java ...
- [转]Android中Xposed框架篇—利用Xposed框架实现拦截系统方法
一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...
- (转)android平台phonegap框架实现原理
(原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...
- 详解Android首选项框架ListPreference
详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...
- Android核心分析之二十Android应用程序框架之无边界设计意图
Android应用程序框架1 无边界设计理念 Android的应用框架的外特性空间的描述在SDK文档(http://androidappdocs.appspot.com/guide/topics/fu ...
随机推荐
- realm-java 源码疑问
JNIEXPORT void JNICALL Java_io_realm_internal_Group_nativeWriteToFile( JNIEnv* env, jobject, jlong n ...
- Android SQLite 加密模块实现入门
安卓的安全性那是众所周知,最近学习安卓apk反编译,发现某些即时通讯软件都封装了自己独立使用的数据库模块(从framework java/C++ 一直到底层的SQLite的C库), 为了防止被root ...
- vs2012中的小技巧
解除起始页: 网站(或者叫项目)-属性-启动选项-使用当前页 发布项目: 有些文件在发布的时候,不能发布到指定文件夹中,所以要手动修改该文件的属性 修改两处: 复制到输出目录:始终复制 生成操作:内容
- FATFS外置UNICODE GBK双向转换码表(转)
源:FATFS外置UNICODE GBK双向转换码表 将UtoG,GtoU双向码表放到存储卡里面实现长文件名,因为FATFS长文件名需要unicode支持, 首先将UtoG.sys,GtoU.sys两 ...
- LPC1768IAP(详解,有上位机)
之前说了stm32的iap编程,今天天气真好,顺手就来说说lpc1788的iap编程(没看前面的请查看stm笔记下的内容) 首先是flash的算法,lpc1768并没有寄存器来让我们操作flash,他 ...
- [转]20个令人惊叹的桌面Docker容器
大家好,今天我们会列出一些运行在Docker容器中的很棒的桌面软件,我们可以在自己的桌面系统中运行它们.Docker 是一个开源项目,提供了一个可以打包.装载和运行任何应用的轻量级容器的开放平台.它没 ...
- [Angular Tutorial] 11 -Custom Filters
在这一步中您将学到如何创建您自己的展示过滤器. ·在先前的步骤中,细节页面展示“true”或“false”来显示某部电话是否有某项功能.在这一步中,我们将使用自定义的过滤器来将这些个字符串转化成符号: ...
- Python3基础 用 函数递归求解 一个数字的阶乘
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...
- [oracle]Oracle角色管理
假如我们直接给每一个用户赋予权限,这将是一个巨大又麻烦的工作,同时也不方便DBA进行管理.通过采用角色,使得: 权限管理更方便.将角色赋予多个用户,实现不同用户相同的授权.如果要修改这些用户的权限,只 ...
- iOS 之 WebView 简单使用
1. 代理 UIWebViewDelegate 2. 创建 UIWebView myWebView=[[UIWebView alloc] initWithFrame:CGRectMake(, ,sel ...