【威哥说】首先非常感谢这位杜同学的建议,为代码提供优化建议,体现了你的细心和技术能力,希望每一位程序员,还有我们磨砺营每一位学员,也要像这位程序员一样,无论业务逻辑简单或复杂,都要尽力优化性能,只有这样,你才能够不断成长,成为高级程序员!
【正文】
今天这篇性能优化的总结源于杜同学对“Android项目实战第二节引导页实现”的一个建议。以下为杜同学发过来的邮件原文:
文章写的很优秀,趁坐地铁的时间看了下。
个人感觉如果是真是的项目的话,为性能考虑,有一个小小的瑕疵:
//滑动后的监听
@Override
public void onPageSelected(int position) {
//循环设置当前页的标记图
for (int i = 0; i < mImageViewArray.length; i++) {
}
}
这种做法是不可取的,虽然圆点图片数量很少,虽然不费什么内存。
修改当前位置的圆点,同时复位上个位置的圆点。定义一个position记录上次的圆点即可。
对技术比较较真,有不敬之处望见谅。
首先非常感谢这位杜同学的建议,为代码提供优化建议,体现了你的细心和技术能力,希望每一位程序员,还有我们磨砺营每一位学员,也要像这位程序员一样,无论业务逻辑简单或复杂,都要尽力优化性能,只有这样,你才能够不断成长,成为高级程序员!
Ok,下面我们看下他提出来的这个问题,我当时为了实现方便,直接的使用循环遍历。逻辑很简单,就是滑动后切换当前选中的状态,清空上一个状态,所以,我们看出,除了当前的和上一个,其它都没有关系,依据这逻辑我们修改下代码:
private int priviousPosition;
//滑动后的监听
@Override
public void onPageSelected(int position) {
//循环设置当前页的标记图
mImageViewArray[position].setBackgroundResource(R.mipmap.viewpager_tag_on);
mImageViewArray[priviousPosition].setBackgroundResource(R.mipmap.viewpager_tag_off);
priviousPosition = position;
首先需要定义一个int变量来记录上一个position,然后分别改变当前页和上一页的背景资源,最后把当前页记录赋值给上一页。
逻辑比较简单,但是相比之前的循环遍历性能上要有优化,代码也更简洁,就像杜同学所说,虽然性能影响不大,但是这样有点小瑕疵。
下面借这个机会,我来给大家总结下项目开发中高性能编码技巧:
一.避免创建不必要的对象
1.字符串拼接,优先考虑StringBuffer和StringBuilder来进行拼接
2.尽量使用基本数据类型来代替封装数据类型,int比Integer要更加高效,其它数据类型也是一样。
3.如果我们明确地知道调用方会将这个返回的String再进行那个拼接操作的话,可以考虑返回一个StringBuffer对象来代替。
4.基本数据类型要优于对象数据类型,类似的,基本数据类型的数组也要优先于对象数据类型的数组。两个平行的数组要比一个封装好的对象数组更加高效,举个例子,sun[]和num[]这样的两个数组,使用起来要比object(sun,num)这样的一个数组高效的多。
我们所要遵守的一个基本原则就是尽可能少创建临时对象,越少的对象意味着越少的GC操作,同时也就意味着越好的程序性能和体验。
二.静态优于抽象
如果你并不需要访问一个对象中的某些字段,只是想调用它的某个方法来去完成一项通用的功能,那么可以将这个方法设置成静态方法,这会让调用的速度提升15%-20%,同时也不用为了调用这个方法而去专门创建对象了,这样还满足了上面的一条原则。另外这也是一种好的编程习惯,因为我们可以放心的调用静态方法,而不用担心调用这个方法后是否会改变对象的状态(静态方法内无法访问非静态字段)。
三.对常量使用static final修饰符
static int num= 35; static String str = “Android”
编译器会为上述代码生成一个初始化方法,称为方法,该方法会在定义类第一次被使用的时候调用。然后这个方法会将35的值赋值到num中,并从字符串常量表中提取一个引用赋值到str上。当赋值完成后,我们就可以通过字段搜寻的方式来去访问具体的值了。
static final int num= 35; static final String str = “Android”
修改之后,定义类不再需要方法,所有的常量都会在dex文件的初始化器中的初始化。
当调用num时可以直接指向35的值,而调用str时会用一种相对轻量级的字符串常量方式,而不是字段搜寻的方式。这种优化方式只对基本数据类型以及String类型的常量有效,对于其它数据类型的常量是无效的。所以,用static final声明常量是一种非常好的习惯。
性能优化是一个大的话题,从代码实现性能优化也有很多要注意的地方,限于篇幅,今天先给大家总结这几个点,希望大家持续关注公众号(mjw-java),关注磨砺营。