성능 최적화 Java(Android) 코드 최적화(4)

이 기사는 다음에서 복제되었습니다: Trinea

이 글은 안드로이드 성능 최적화 - 자바(안드로이드) 코드 최적화의 세 번째 부분입니다. 캐싱, 비동기, 지연, 데이터 저장, 알고리즘, JNI, 로직 및 기타 최적화 방법을 포함하여 Java 코드의 성능 최적화 방법과 네트워크 최적화를 주로 소개합니다 .

1. 실행 시간 단축
이 부분에는 캐싱, 데이터 저장 최적화, 알고리즘 최적화, JNI, 로직 최적화, 수요 최적화 등 여러 가지 최적화 방법이 포함됩니다.
(1) 캐시
캐시에는 주로 객체 캐시, IO 캐시, 네트워크 캐시, DB 캐시가 포함되며, 객체 캐시는 메모리 할당을 줄일 수 있고, IO 캐시는 디스크 읽기 및 쓰기 횟수를 줄이며, 네트워크 캐시는 네트워크 전송을 줄이고, DB 캐시는 데이터베이스를 줄입니다. 접속 빈도.
메모리, 파일, 데이터베이스, 네트워크 등의 읽기/쓰기 속도 중 메모리가 가장 좋은데 그 속도는 크기에 따라 달라지므로 자주 접근해야 하거나 한번 접근하면 많은 돈을 소모하는 데이터를 저장하는 것이 좋습니다. 캐시.

 

캐시는 Android에서 일반적으로 사용됩니다:
a.   스레드 풀
b.   Android 이미지 캐시 , Android 이미지 Sdcard 캐시 , 데이터 프리페치 캐시
c. 메시지 캐시는
다음과 같이 handler.obtainMessage를 통해 이전 메시지를 재사용합니다.

d.  ListView 캐시

e.  네트워크 캐싱:
데이터베이스는 http 응답을 캐시하고 http 헤더 정보의 Cache-Control 필드를 기반으로 캐시 만료 시간을 결정합니다.
f. 파일 IO 캐싱은
캐싱 전략이 적용된 입력 스트림을 사용하며, BufferedInputStream은 InputStream을, BufferedReader는 Reader를, BufferedReader는 BufferedInputStream을 대체하며 파일 및 네트워크 IO 모두에 적용 가능합니다.
g.  레이아웃 캐시
h. 자주 액세스해야 하거나 액세스한 후 많은 양의 데이터를 소비하는 기타 데이터 캐시

 

(2) 데이터 저장 최적화에는
데이터 유형 및 데이터 구조의 선택이 포함됩니다.
a. 데이터 유형 선택:
문자열 접합에는 String 대신 StringBuilder를 사용하고, 비동시 상황에서는 StringBuffer 대신 StringBuilder를 사용합니다. 100자 정도의 문자열 길이에 대한 일반적인 이해가 있는 경우 new StringBuilder(128)를 사용하여 초기 크기를 직접 지정하면 공간이 부족할 때 재할당을 줄일 수 있습니다.
long double과 같은 64비트 유형의 처리는 int와 같은 32비트 유형의 처리보다 느립니다.
SoftReference 및 WeakReference를 사용하는 것은 일반적인 Strong 응용 프로그램보다 시스템 가비지 수집에 더 도움이 됩니다.
최종 유형은 상수 영역에 저장되고 읽기에 더 효율적입니다.
LocalBroadcastManager는 일반 BroadcastReceiver를 대체하며 효율성은 동일합니다. 보안이 더 높습니다.

 

b. 数据结构选择
常见的数据结构选择如:
ArrayList和LinkedList的选择,ArrayList根据index取值更快,LinkedList更占内存、随机插入删除更快速、扩容效率更高。一般推荐ArrayList。
ArrayList、HashMap、LinkedHashMap、HashSet的选择,hash系列数据结构查询速度更优,ArrayList存储有序元素,HashMap为键值对数据结构,LinkedHashMap可以记住加入次序的hashMap,HashSet不允许重复元素。
HashMap、WeakHashMap选择,WeakHashMap中元素可在适当时候被系统垃圾回收器自动回收,所以适合在内存紧张型中使用。
Collections.synchronizedMap和ConcurrentHashMap的选择,ConcurrentHashMap为细分锁,锁粒度更小,并发性能更优。Collections.synchronizedMap为对象锁,自己添加函数进行锁控制更方便。

 

Android也提供了一些性能更优的数据类型,如SparseArray、SparseBooleanArray、SparseIntArray、Pair。
Sparse系列的数据结构是为key为int情况的特殊处理,采用二分查找及简单的数组存储,加上不需要泛型转换的开销,相对Map来说性能更优。不过我不太明白为啥默认的容量大小是10,是做过数据统计吗,还是说现在的内存优化不需要考虑这些东西,写16会死吗,还是建议大家根据自己可能的容量设置初始值。

 

(3). 算法优化
这个主题比较大,需要具体问题具体分析,尽量不用O(n*n)时间复杂度以上的算法,必要时候可用空间换时间。
查询考虑hash和二分,尽量不用递归。可以从结构之法 算法之道微软、Google等面试题学习。

 

(4). JNI
Android应用程序大都通过Java开发,需要Dalvik的JIT编译器将Java字节码转换成本地代码运行,而本地代码可以直接由设备管理器直接执行,节省了中间步骤,所以执行速度更快。不过需要注意从Java空间切换到本地空间需要开销,同时JIT编译器也能生成优化的本地代码,所以糟糕的本地代码不一定性能更优。
这个优化点会在后面单独用一片博客介绍。

 

(5). 逻辑优化
这个不同于算法,主要是理清程序逻辑,减少不必要的操作。

 

(6). 需求优化
这个就不说了,对于sb的需求可能带来的性能问题,只能说做为一个合格的程序员不能只是执行者,要学会说NO。不过不能拿这种接口敷衍产品经理哦。

 

2、异步,利用多线程提高TPS
充分利用多核Cpu优势,利用线程解决密集型计算、IO、网络等操作。
关于多线程可参考:Java线程池
在Android应用程序中由于系统ANR的限制,将可能造成主线程超时操作放入另外的工作线程中。在工作线程中可以通过handler和主线程交互。

 

3、提前或延迟操作,错开时间段提高TPS
(1) 延迟操作

不在Activity、Service、BroadcastReceiver的生命周期等对响应时间敏感函数中执行耗时操作,可适当delay。
Java中延迟操作可使用ScheduledExecutorService,不推荐使用Timer.schedule;
Android中除了支持ScheduledExecutorService之外,还有一些delay操作,如
handler.postDelayed,handler.postAtTime,handler.sendMessageDelayed,View.postDelayed,AlarmManager定时等。

 

(2) 提前操作
对于第一次调用较耗时操作,可统一放到初始化中,将耗时提前。如得到壁纸wallpaperManager.getDrawable();

 

4、网络优化
以下是网络优化中一些客户端和服务器端需要尽量遵守的准则:
a. 图片必须缓存,最好根据机型做图片做图片适配
b. 所有http请求必须添加httptimeout

c. 开启gzip压缩
d. api接口数据以json格式返回,而不是xml或html
e. 根据http头信息中的Cache-Control及expires域确定是否缓存请求结果。

f. 네트워크에서 요청한 연결이 연결 유지인지 확인합니다.
g. 네트워크 요청 수를 줄이고 서버 측에서 요청을 적절하게 병합합니다.
h. 리디렉션 수를 줄입니다.
i. API 인터페이스의 서버측 응답 시간은 100ms를 초과하지 않습니다.
Google은 모바일 웹 페이지의 속도를 1초로 줄이는 프로젝트를 진행하고 있습니다. https:/ 에 주목하고 있습니다. /developers.google.com/speed/docs/insights/ 모바일


추천

출처blog.csdn.net/skylovesky/article/details/26462985