zoukankan      html  css  js  c++  java
  • 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+"
    ");
    
                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+"
    ");
    
                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 .

  • 相关阅读:
    虚拟机中Linux 下安装tools
    各个复位标志解析,让我们对MCU的程序的健康更有把控
    用过的两种鼠标右键添加快捷指令方法
    一个ftp协议传输文件之后执行脚本无法工作的情况
    一文入门Linux下gdb调试(二)
    一文入门Linux下gdb调试(一)
    VS CODE远程办公篇一
    Kwp2000协议的应用(程序后续篇)
    Kwp2000协议的应用(程序原理篇)
    Kwp2000协议的应用(硬件原理使用篇)
  • 原文地址:https://www.cnblogs.com/depyuka/p/3861931.html
Copyright © 2011-2022 走看看