Android 性能优化 (十三) 数据结构算法优化 秒变大神 Protocol Buffer

4大优化

1.图片数据优化

2.集合的优化

3.排序算法优化

4.传输数据优化

 

今天运行了一下:Android Lint 工具,看到了程序中关于这块的问题

1.图片优化

用ARGB_4444替代ARGB_8888

  • ALPHA_8——代表8位Alpha位图 
  • ARGB_4444——代表16位ARGB位图
  • ARGB_8888——代表32位ARGB位图
  • RGB_565——代表8位RGB位图

位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真

2.集合的优化

Java语言和Android源码里面有很多现成的轮子,我们在使用这些数据结构的时候,要知其所以然,从源码分析这些数据结构的原理和特点,选取最适合的拿来用。

 

1.使用SparseArray、ArrayMap代替HashMap

 

SparseArray指的是稀疏数组(Sparse array),所谓稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。

 

google推荐使用其代替HashMap, 其内部实现了压缩算法,可以进行矩阵压缩,大大减少了存储空间,节约内存。此外它的查找算法是二分法,提高了查找的效率。

 

数据量小于1000时,使用ArrayMap可以避免HashMap内存翻倍的问题,以int为key的HashMap可以用SparseArray代替,缺点是乱序查找添加删除效率不如HashMap

 

ArrayMap的使用并不能提升反应时间,却能够节省内存空间,当数据量很大时,使用ArrayMap,以时间换空间,防止出现OOM。Bundle实现使用了ArrayMap。

 

ArrayMap与HashMap有四点不同

 

a.储存方式不同

 

ArrayMap储存数据和HashMap不同,它没有Entry这个东西,而是用数组来保存数据

 

b.扩容操作不同

 

HashMap容量不足时,会新建double容量table返回,而ArrayMap采用copy方式,并且收缩数组,释放不必要的容量。

 

c.数组可收缩

 

去掉不使用的容量,节省空间。

 

d.查找方式不同

 

ArrayMap采用二分查找,查找效率比HashMap高,但是插入数据会涉及大量的数据搬移

 

和SparseArray一样,数据量适中时(小于1000)使用ArrayMap可以避免HashMap内存翻倍的问题。数据条数大于1000时乱序操作效率很低,不推荐使用。

 

 

2.根据情况选择适合的collection容器

 

根据实际情况选择ArrayList或者LinkedList。

 

a.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 

b.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 

c.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

 

3.根据实际情况,选择合适的算法

 

a.关于查找的算法很多种:基本查找、二分查找、二叉树、斐波那契等

 

它们时间复杂度和空间复杂度不同,选择适合的算法事半功倍

 

比如一个顺序队列n个数据,选择基本查找的时间复杂度为O(n),而二分查找时间复杂度为O(log 2 n),显然n越大,基本查找消耗的时间越久,性能损耗越高。

 

再比如,查询某个文件,你可以采用基本查找、也可以先排序、再进行二分查找。

 

4.采用ConcurrentHashMap处理需要线程同步的Map

 

ConcurrentHashMap相较于HashMap,它是线程同步的,而且不是简单的加锁而已,而是采用了分段加锁的技术segment(类似HashTable)来进行加锁,性能比单纯的全局加锁提升10几倍。

5.可以尝试自己造轮子

现成的数据结构不一定是最好的,他们往往是最稳定的,它们的都不是凭空产生的,条件合适,可以自己写数据结构,自己造的肯定最适合你。

 

总之,用于现实世界的存储,我们使用的工具和建模。每种数据结构有自己的优点和缺点,根据实际情况采用合适的数据结构。

而算法,在这么多的数据中如何做到最快的插入,查找,删除,也是在追求更快。

 

数据结构和算法重要性远不止这些,它是一门很高深的学科,摘录一段对数据结构和算法比较深刻的描述

如果说 Java 是自动档轿车,C 就是手动档吉普。数据结构呢?是变速箱的工作原理。你完全可以不知道变速箱怎样工作,就把自动档的车子从 A 开到 B,而且未必就比懂得的人慢。写程序这件事,和开车一样,经验可以起到很大作用,但如果你不知道底层是怎么工作的,就永远只能开车,既不会修车,也不能造车。如果你对这两件事都不感兴趣也就罢了,数据结构懂得用就好。但若你此生在编程领域还有点更高的追求,数据结构是绕不开的课题。

 

Java 替你做了太多事情,那么多动不动还支持范型的容器类,加上垃圾收集,会让你觉得编程很容易。但你有没有想过,那些容器类是怎么来的,以及它存在的意义是什么?最粗浅的,比如 ArrayList 这个类,你想过它的存在是多么大的福利吗——一个可以随机访问、自动增加容量的数组,这种东西 C 是没有的,要自己实现。但是,具体怎么实现呢?如果你对这种问题感兴趣,那数据结构是一定要看的。甚至,面向对象编程范式本身,就是个数据结构问题:怎么才能把数据和操作数据的方法封装到一起,来造出 class / prototype 这种东西?

3.排序算法优化

比如:冒泡排序的算法优化

4.Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式,性能比 Json、XML 真的强!太!多!

 

今天,我将讲解Protocol Buffer使用的源码分析,并解决以下两个问题: 
a. Protocol Buffer序列化速度 & 反序列化速度为何如此快 
b. Protocol Buffer的数据压缩效果为何如此好,即序列化后的数据量体积小

 

1. 定义

 

一种 结构化数据 的数据存储格式(类似于 `XML、Json` )

Google 出品 (开源)

Protocol Buffer 目前有两个版本:proto2 和 proto3

因为proto3 还是beta 版,所以本次讲解是 proto2

2. 作用

 

通过将 结构化的数据 进行 串行化(序列化),从而实现 数据存储 / RPC 数据交换的功能

 

序列化: 将 数据结构或对象 转换成 二进制串 的过程

反序列化:将在序列化过程中所生成的二进制串 转换成 数据结构或者对象 的过程

3. 特点

 

对比于 常见的 XML、Json 数据存储格式,Protocol Buffer有如下特点:

 

 

4. 应用场景

 

传输数据量大 & 网络环境不稳定 的数据存储、RPC 数据交换 的需求场景

 

如 即时IM (QQ、微信)的需求场景

总结

 

在 传输数据量较大的需求场景下,Protocol Buffer比XML、Json 更小、更快、使用 & 维护更简单!

 

5. 使用流程

 

关于 Protocol Buffer 的使用流程,具体请看我写的文章:快来看看Google出品的Protocol Buffer,别只会用Json和XML了

 

6. 知识基础

 

6.1 网络通信协议

 

序列化 & 反序列化 属于通讯协议的一部分

通讯协议采用分层模型:TCP/IP模型(四层) & OSI 模型 (七层)

 

 

序列化 / 反序列化 属于 TCP/IP模型 应用层 和 OSI`模型 展示层的主要功能:

 

(序列化)把 应用层的对象 转换成 二进制串

(反序列化)把 二进制串 转换成 应用层的对象

所以, Protocol Buffer属于 TCP/IP模型的应用层 & OSI模型的展示层

 

6.2 数据结构、对象与二进制串

 

不同的计算机语言中,数据结构,对象以及二进制串的表示方式并不相同。

 

a. 对于数据结构和对象

 

对于面向对象的语言(如Java):对象 = Object = 类的实例化;在Java中最接近数据结构 即 POJO(Plain Old Java Object),或Javabean(只有 setter/getter 方法的类)

 

对于半面向对象的语言(如C++),对象 = class,数据结构 = struct

 

b. 二进制串

 

对于C++,因为具有内存操作符,所以 二进制串 容易理解:C++的字符串可以直接被传输层使用,因为其本质上就是以 '\0' 结尾的存储在内存中的二进制串

对于 Java,二进制串 = 字节数组 =byte[] 

byte 属于 Java 的八种基本数据类型 

二进制串 容易和 String混淆:String 一种特殊对象(Object)。对于跨语言间的通讯,序列化后的数据当然不能是某种语言的特殊数据类型。

 

6.3 Protocol Buffer 的序列化原理 & 数据存储方式

 

Protocol Buffer 的序列化原理主要在于 独特的编码方式 & 数据存储方式

具体请看文章 Protocol Buffer 序列化原理大揭秘 - 为什么Protocol Buffer性能这么好?

7. 源码分析

 

7.1 核心分析内容

 

在下面的源码分析中,主要分析的是: 

1. Protocol Buffer具体是如何进行序列化 & 反序列化 ? 

2. 与 XML、Json 相比,Protocol Buffer 序列化 & 反序列化速度 为什么如此快 & 序列化后的数据体积这么小?

 

本文主要讲解Protocol Buffer在 Android 平台上的应用,即 Java 

平台

 

参考博客:

https://blog.csdn.net/carson_ho/article/details/70902349

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值