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