Android学习之——优化篇(1)

一、优化的品质

1.简练。2.可读性强。3.模块化;4.层次性;5.设计良好。6.高效。7.优雅;8.清晰。

二、常见的编程规范

    1. 基本要求

· 结构清晰,简单易懂。单个函数不超过100行。目标明白,代码精简

· 尽量使用标准库函数和公共函数

· 不任意定义全局变量。尽量使用局部变量

· 使用括号。以避免二义性

    2. 可读性要求

· 可读性第一,效率第二

· 保证凝视与代码全然一致

· 都有文件头说明,都有函数头说明

· 定义变量时,凝视能反映含义;常量定义有说明

· 处理过程每一个阶段都有凝视说明;典型算法亦是如此

· 使用缩进;循环,分支不超过5层

· 空白行也是一种特殊的凝视;一目了然的语句不加凝视

    3. 结构化要求

· 禁止出现两条等价的支路;用case实现多路分支

· 避免从循环引出多个出口;函数仅仅有一个出口

· 不要用条件赋值语句;避免不必要的分支;不要轻易用条件分支去替换逻辑表达式

    4. 正确性与容错性要求

· 首先保证正确。其次才是优美

· 时刻回头检查。改动前考虑对其它程序的影响

· 变量调用前必须被初始化

· 对用户输入进行合法性检查

· 不要比較浮点数的相等,如:10.0*0.1 == 1.0

· 主动处理程序与环境状态的关系,如:打印机是否联机,文件是否能逻辑锁定

· 做单元測试

    5. 可重用性要求

· 反复使用的完毕相对独立功能的算法或代码应抽象为公共控件或类

· 公共空间或类应考虑面向对象思想。降低外界联系。考虑独立性或封装性

三、程序性能測试

    1. 计算性能

Java提供了 System.currentTimeMillis()方法,能够得到毫秒级的当前时间,通过该方法来计算运行某一段代码所消耗的时间。

我们能够通过 Java的 java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler 利用动态代理来解决枯燥的输入System.currentTimeMillis()
来计算运行时间的问题。

能够參考该样例:http://www.iteye.com/topic/683613

    2. 内存消耗

利用 Runtime 类的freeMemory() 和 totalMemory() 方法来考虑程序中的对象所消耗的虚拟机堆空间

參考链接:http://blog.csdn.net/wgw335363240/article/details/8878644

    3. 启动时间

    4. 可伸缩性

    5. 用户察觉性能

四、 0基础优化

在 Java 程序中 性能问题大部分原因并不在于 Java 语言,而是在程序本身。养成好的代码编写习惯很重要。

1. 尽量指定类的 final 修饰符

带有final修饰符的类不可派生。

假设指定一个类为 final 。则该类全部的方法都是 final 。

Java 编译器会寻找机会内联 (inline) 全部的 final 方法。此举能使性能平均提高 50%。

2. 尽量重用对象

特别是 String 对象的使用中,出现字符串连接情况应用 StringBuffer 取代。

3. 尽量使用局部变量

调用方法时传递的參数以及在调用中创建的暂时变量都保存在栈(Stack)中。速度较快。

其它的都保存在堆(Heap)中。速度较慢。

4. 不要反复初始化变量

默认情况下。调用类的构造函数时,Java 会把变量初始化成确定的值,全部的对象被设置成 null,整数变量设置为 0。float 和 double 为 0.0。逻辑为 false。当一个类从还有一个类派生时。尤为要注意,由于用 new 关键词创建一个对象时,构造函数链中的全部构造函数都会被自己主动调用。

5. Java + Oracle 的应用开发中, Java内嵌的SQL语句使用大写

6. Java 编译过程中,数据库连接、I/O 流操作要及时关闭释放

7. 对象使用完成后,手动设置为 null

8. 在使用同步机制时,应尽量用法同步取代代码块同步

9. 尽量降低对变量的反复计算

如:

for(int i = 0; i< list.size(); i++){....}

应替换为:

for(int i = 0,int len = list.size(); i < len; i++){....}

10. 尽量採用 lazy loading 的策略。在须要的时候才開始创建

如:

String str = "aaa";
if(i == 1){
	list.add(str);
}

应替换为:

if(i == 1){
	String str = "aaa";
	list.add(str);
}

11. 慎用异常,异常对性能不利

抛出异常首先要创建一个新的对象。

Throwable 接口的构造函数用名为 fillInStackTrace() 的本地方法,fillInStackTrace() 方法检查栈。收集调用跟踪信息。

仅仅要有异常被抛出,VM 就必要调整调用栈。由于在处理过程中创建了一个新的对象。

异常仅仅能用于错误处理。不应该用来控制程序流程。

12. 不要再循环中使用 Try/Catch 语句。应把其放在最外层

13. StringBuffer 的使用。 StringBuffer 表示了可变的、可写的字符串

StringBuffer();			//默认分配16个字符的空间
StringBuffer(int size);		//分配size个字符的空间
StringBuffer(String str);	//分配16个字符+str.length()个字符空间

你能够通过 StringBuffer 的构造函数来设定它的初始化容量,这样能够明显地提升性能。

使用一个合适的容量值来初始化 StringBuffer 永远都是一个最佳的建议。

14. 合理的使用 Java 类 java.util.Vector

简单的说。一个Vector 就是一个 java.lang.Object 实例的数组。

Vector 与数组相似。考虑例如以下样例:

Object obj = new Object();
Vector v = new Vector(100000);
for(int i = 0; i < 100000; i++){
	v.add(0, obj);
}

除非有绝对充足的理由要求每次都把新元素插入到 Vector 的前面,否则上面的代码对性能不利。以下的代码比上面的要快好几个数量级:

Object obj = new Object();
Vector v = new Vector(100000);
for(int i = 0; i < 100000; i++){
	v.add(obj);
}

相同的规则适用于 remove() 方法。因为 Vector 中各个元素之间不能含有“空隙”。删除除最后一个元素之外的随意其它元素都导致被删除元素之后的元素向前移动。也就是说。从 Vector 删除最后一个元素要比删除第一个元素的“开销”低好几倍。

for(int i = 0;  i++; i < v.length)

改成

int size = v.size()
for(int i = 0; i++;i < size)

15. 当复制大量数据时,使用 System.arraycopy()
命令

16. 代码重构:增强代码可读性

17. 不用new 关键词创建类的实例

将对象实现 Clonewable 接口,调用它的clone() 方法。

在设计模式的场合。用工厂模式创建对象,则改用 clone() 方法创建新的对象实例很easy。以下是工厂模式的一个典型实现:

public static Credit getNewCredit(){
	return new Credit();
}

改进后的代码使用clone() 方法。例如以下:

private static Credit BaseCredit = new Credit();
public static Credit getNewCredit(){
	return (Credit)BaseCredit.clone();
}

上面的思路对于数组的处理相同非常实用。

18. 乘法和除法

a = a * 8; b = b * 2; 

改成移位操作:

a = a << 3; b = b << 1;

19. 不要讲数组申明为:public static final

20. HaspMap 的遍历效率

例如以下两种方法:

Map<String, String[]> paraMap = new HashMap<String, String[]>();
//第一个循环
Set<String> appFieldDefIds = paraMap.keySet();
for(String appFieldDefId : appFieldDefIds){
	String[] values = paraMap.get(appFieldDefId);
}
//第二个循环
for(Entry<String, String[]> entry : paraMap.entrySet()){
	String appFieldDefId = entry.getKey();
	String[] values = entry.getValue();
}

第一种的实现的效率明显不如另外一种实现。

第一种是先从 HashMap 中取得 keySet 值,另外一种则是每次循环时都取值,添加了CPU要处理的任务。

依照 Map 的概念来看,将key 和 value 分开操作在这里不是个好选择

21. array 和 ArrayList 的使用

array 最高效,但容量固定且无法改变

ArrayList :容量动态增长,但牺牲效率。

详细使用视情况而定。

22. 尽量使用 HashMap 和 ArrayList

除非必要,否则不推荐使用 HashTable。和Vector。他们因为使用同步机制,导致性能的开销。

23. StringBuffer 和 StringBuilder 的差别

java.lang.StringBuffer 线程安全的可变字符序列。一个类似于 String 的字符串缓冲区。但不能改动。

假设性能瓶颈能确定是在 StringBuffer 上。而且确定你的模块不会执行在多线程模式下,否则还是用 StringBuffer 吧。

欢迎转载,转载注明出处,谢谢

Mr.傅:阅读自《Android应用开发揭秘》

时间: 2024-10-24 15:04:01

Android学习之——优化篇(1)的相关文章

Android学习之——优化篇(2)

一.高级优化 上篇主要从初级优化的方式,本篇主要将从程序运行性能的角度出发,分析各种常用方案的不足,并给出对象池技术.基础数据类型替换法.屏蔽函数计算三种能够节省资源开销和处理器时间的优化策略. 目前普遍采用的优化方案有:     · 优化循环,通过重新组织重复的子表达式来提高循环体的运行性能     · 减少使用对象的数量来提高运行性能     · 缩减网络传输数据来缩短等待时间等 本篇学习另外三种性能优化的策略:     1. 采用对象池技术,提高对象的利用率 Java 中创建和释放对象会占

android学习第1篇:windows下android环境搭建:adt-bundle

安卓学习开始了! 在windows上搭建安卓开发环境,看似简单,其实问题很多,我整整搭建了5天才搞定,当然,也是因为工作有些忙的原因,时间不太多,OK,本篇教程,我会将我遇到的所有问题都写上,希望看到这篇博客的朋友,不会犯同样的错误. 一.搭建JAVA开发环境 1.基本概念 如果你会JAVA,那直接略过就行. http://blog.csdn.net/alspwx/article/details/20799017 这篇博客,是我以前转载的别人的,主要是介绍:J2EE\J2ME\JVM\JRE\J

Android学习笔记(第二篇)View中的五大布局

PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念   view是什么呢?我们已经知道一个Activity是Android的显示层,但是Activity是不能直接显示在屏幕上的,它也像JSP那样,显示的东西是html,那么Android也不例外,Activity是一个抽象的壳子,而显示的东西就是view或者是viewgroup(图形用户组件)....   有了这个概念,我们就清楚view是如何

Android学习笔记(第一篇)编写第一个程序Hello World+Activity

  PS:实验室里就我一个搞Android的,像人家学习J2EE的,还有人带着去学,我这样没人带的就只能自己摸爬滚打了,也总算是把大部分的基础算是学完了,终于开始正式的搞Android了...无人带的一介菜鸟,我还是自己默默的努力吧... 学习内容: 1.编写第一个Hello World程序..   学习Android,那么就需要有一个编译器来集成这个环境,然后在搭建好环境的编译器上进行开发就可以了,我所介绍的都是在Eclipse上来进行Android的开发...环境搭建在这里我就不进行介绍了.

Android学习之界面篇(九)SurfaceView简单学习

知识点: surfaceview介绍 surfaceview与View的区别,surface与surfaceview的区别 实例创建与使用 SurfaceHolder.Callback的使用,surfaceHolder可以看作是surfaceview的控制器,控制图形的大小,像素等. 在主函数中回调函数的使用getHolder.addCallback(this) canvas的锁定与解锁,绘制图形之前锁定画布,绘制结束之后解锁画布. canvas的save与restore, canvas画布的各

Android学习之界面篇(七)侧滑菜单的实现

侧滑菜单的实现方式: SlidingMenu开源库:https://github.com/jfeinstein10/SlidingMenu DrawerLayout:是2013年谷歌IO大会上由谷歌官方发布的,包含在support v4包中. 官方定义:http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html 使用说明:http://developer.android.com/traini

《Android学习指南》文件夹

转自:http://android.yaohuiji.com/about Android学习指南的内容分类: 分类 描写叙述 0.学习Android必备的Java基础知识 没有Java基础的朋友,请不要先看Android的课程,这样会非常累. 1.Android学习指南基础篇 对于有Java基础的朋友,能够通过本分类60讲左右的课程,打下比較坚实的基础. 2.Android学习指南项目实训篇 对于学过"1.Android2.2学习指南基础篇"的朋友,能够通过本分类项目的联系,加深对基础

Android学习之-RecyclerView带刺的玫瑰

我的小鱼你醒了, 还认识早晨吗? 昨夜你曾经说, 愿夜幕永不开启 - 上述小诗先逗比一下,接下来切入正题: 自从RecyclerView的诞生起,人们就为她贴上了高贵的标签:她灵活华丽高度可定制,而另一边ListView确已是明日黄花:人们趋之若鹜的奔向了RecyclerView赞美她吹捧她似乎一切的一切都尽在他们的掌握中:各大技术论坛开始讲解RecyclerView是多么的好用:于是乎我也加入了使用RecyclerView的行列中,哦不!是混入了: 初识RecyclerView 说实在的我不愿

《Android学习指南》目录

源:<Android学习指南>目录 Android学习指南的内容分类: 分类 描述 0.学习Android必备的Java基础知识 没有Java基础的朋友,请不要先看Android的课程,这样会很累. 1.Android学习指南基础篇 对于有Java基础的朋友,可以通过本分类60讲左右的课程,打下比较坚实的基础. 2.Android学习指南项目实训篇 对于学过“1.Android2.2学习指南基础篇”的朋友,可以通过本分类项目的联系,加深对基础知识的理解和熟练运用. 3.Android学习指南提