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框架性能测试结果的更多相关文章

  1. Android/Linux下CGroup框架分析及其使用

    1 cgroup介绍 CGroup是control group的简称,它为Linux kernel提供一种任务聚集和划分的机制,可以限制.记录.隔离进程组(process groups)所使用的资源( ...

  2. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  3. Android 下的usb框架及功能点【转】

    本文转载自:https://blog.csdn.net/tianruxishui/article/details/37902959 有关USB android框架的链接 http://blog.sin ...

  4. [Android]Android端ORM框架——RapidORM(v2.0)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5626716.html [Android]Android端ORM ...

  5. Android开源测试框架学习

    近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料. Android测试大致分三大块: 代码层测试 用户操作模拟,功能测试 安装部署及稳定性测试 代码层测试 对于一般java ...

  6. [转]Android中Xposed框架篇—利用Xposed框架实现拦截系统方法

    一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...

  7. (转)android平台phonegap框架实现原理

    (原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...

  8. 详解Android首选项框架ListPreference

    详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...

  9. Android核心分析之二十Android应用程序框架之无边界设计意图

    Android应用程序框架1 无边界设计理念 Android的应用框架的外特性空间的描述在SDK文档(http://androidappdocs.appspot.com/guide/topics/fu ...

随机推荐

  1. jQuery修改css属性

    jQuery CSS 操作jQuery 拥有三种用于 CSS 操作的重要函数:$(selector).css(name,value)$(selector).css({properties})$(sel ...

  2. POJ 2609 Ferry Loading

    双塔DP+输出路径. 由于内存限制,DP只能开滚动数组来记录. 我的写法比较渣,但是POJ能AC,但是ZOJ依旧MLE,更加奇怪的是Uva上无论怎么改都是WA,其他人POJ过的交到Uva也是WA. # ...

  3. 制作毛玻璃效果 分类: ios技术 2015-07-14 09:03 240人阅读 评论(0) 收藏

    //添加一个图片     UIImageView *imageview = [[UIImageView alloc]init];     imageview.frame = CGRectMake(10 ...

  4. X-006 FriendlyARM tiny4412 u-boot移植之Debug串口用起来

    <<<<<<<<<<<<<<<<<<<<<<<<< ...

  5. Yii实现Password Repeat Validate Rule

    在使用Yii时遇到这样的需求:在一个注册的页面输入两次密码,并验证两次输入是否一致.可是password的repeat的字段在数据库 并不存在.问题来了,如何创建一个password_repeat的属 ...

  6. 使用 System.Transactions 进行事物管理

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  7. Bzoj 1936

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1396 题解:待更 代码:待更 开始时间: 结束时间:

  8. iOS 之 界面编程解析

    参考:http://www.cocoachina.com/design/20151225/14789.html 0. 内容概述 基础与本质:说明普遍意义上的UI系统的三大模块,让读者从整体上对UI系统 ...

  9. PHP批量上传一次点击选中多个

    首先前端部分需要设置好控件,这里使用HTML5 中 input 的新增属性 multiple 可以很好的解决了以往上传多个需要点击多次"上传按钮"的麻烦: <form act ...

  10. Xcode 添加前缀

    项目导航栏>Targets>右侧的Utilities>Class Prefix