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 ...
随机推荐
- IOS开发-OC学习-常用功能代码片段整理
IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是 ...
- AutoMapper使用说明
1.引用命名空间 using AutoMapper;using AutoMapper.Mappers; 2.实体类和dto public class Order { public int orderi ...
- C++的封装性
C++的封装性 C++的阶段,我想根据C++的一些特有的特性分别写一些专题,每个专题我都捎带讲一些语法,当然不会很多,我还是会像C语言那样,内存结构贯穿始终,有汇编就有真相…… 本专题,我们讲述封装性 ...
- .Net普通三层 到 工厂模式->线程内唯一+单元工作模式->WebService分布式三层
在软件世界分层的思想无处不在 主要是为了提高软件系统的维护性,扩展性,复用性和解耦等 软件的三层构架是一种最基本的分层思想的体现 结构图大体如下: 如此一来,开发人员可以只关注其中一层,而无需关心下一 ...
- UVa 10523 - Very Easy !!!
题目大意:给你一个公式,直接按照式子计算就可以了,要用到大数. import java.io.*; import java.util.*; import java.math.*; class Main ...
- 虔诚的墓主人(bzoj 1227)
Description 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意提前为自己 ...
- c#和java中的方法覆盖——virtual、override、new
多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...
- jQuery图片轮播的具体实现
先看一看html代码,以及对应的css代码: <div id="scrollPics"> <ul class="slider" > ...
- MongoDB复制集环境搭建
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://suifu.blog.51cto.com/9167728/1853478 环境介绍 ...
- iOS 之 NSUserDefault
1. 概念 NSUserDefaults是一种特殊的property list.是系统封装的属性列表,方便记录简单的数据. 2. 使用说明 2.1. 创建NSUserDefaults NSUserDe ...