背景
当我们谈到性能优化,更多的同学可能想到的是系统层面的性能优化。比如在一个Web服务程序中,通过Redis或者其它缓存来提升网站访问的速度等。对于程序代码本身的优化却比较少。这一方面是编译器为我们做了很多优化工作,另外一方面是觉得系统层面的优化效果更明显,也更高大上。实际上,除了系统层面的性能优化外,在程序代码层面的性能优化效果也是非常好的。
数组分配
int[][] array = new int[1024][1024]; for (int i = 0; i < 1024; i++) { for (int j = 0; j < 1024; j++) { array[j][i] = 1; } } int[][] array = new int[1024][1024]; for (int i = 0; i < 1024; i++) { for (int j = 0; j < 1024; j++) { array[i][j] = 1; } }
上面两段代码作用完全相同,差异在于对数组元素的访问顺序,前者是逐列访问,而后者是逐行访问。测试下来,后者比前者快2倍以上。即java分配内存,在数组中是逐行分配的
这两者是有性能差异的。核心点在于访问的是连续的地址空间,还是跳跃的地址空间。
性能差异原因:
缓存行的存在,导致跳跃的地址空间没法命中缓存数据,需要再去加载。
字符串累加
String str = ""; for (int i = 0; i < 1024; i++) { str += i; }
这样会生成很多无用的字符串,建议用StringBuilder。
位运算代替模运算
可以参考HashMap计算key的hash值的方式,用位运算代替模运算,可以加快运算速度。
引用与拷贝
传递对象参数时会涉及拷贝对象,通过一种成为引用的机制实现了对象地址的传递,这样就避免了拷贝的过程(这就是传值与传址的差异)。