在编写循环结构的程序很多程序会犯一个错误,就是在循环判断体中做重复计算。
例如:for(int i = 0;i <list.size; i ++) {
…
}
应替换为:
for(int i = 0,int len = list.size();i < len; i ++) {
…
}
在循环的语句结构中,每次跳转都需要比较,判断是否进行继续循环,但是最好不要在比较之前有
计算的语句,尽量避免。否则循环中重复计算,效率会非常低。
今天开发的静态扫描检测器就是检查这个问题,
时刻提醒程序员注意该问题。
扫描器运行结果如图:
该检测器详细介绍:
1.1.1 PERFORMANCE_LOOP_CALCULATE
循环中重复计算
1.1.1.1 版本
Verson:1.2.0
1.1.1.2 作者
Author: River.liu
Date : 2010.4.17
Email : liuhanhong@yahoo.com.cn
1.1.1.3 原理
在循环的语句结构中,每次跳转都需要比较,判断是否进行继续循环,但是最好不要在比较之前有
计算的语句,尽量避免。否则循环中重复计算,效率会非常低。
例如:for(int i = 0;i < list.size; i ++) {
…
}
应替换为:
for(int i = 0,int len = list.size();i < len; i ++) {
…
}
1.1.1.4 开发原理
当遇到循环指令,就查找之前保存的preDirectCount个指令,判断是否存在includeMethordsDirect指定的指令,同时判断是否调用了includeMethords指定的方法,如果存在就表示存在循环计算。
1.1.1.5 配置说明
配置文件pluginConfig.properties在插件的jar包里面,直接修改里面的配置项目,再放回jar包就可以了。
1.1.1.5.1 isOpen
是否启用该检测器。
PERFORMANCE_LOOP_CALCULATE.isOpen=true
1.1.1.5.2 includeMethords
在循环中进行计算的方法的名字,比如list.size()为szie
每个方法名以逗号分隔
PERFORMANCE_LOOP_CALCULATE.includeMethords=size
1.1.1.5.3 preDirectCount
循环指令保存的前preDirectCount个指令,
也就是循环指令的前preDirectCount指令中调用了指定的方法就算匹配了
PERFORMANCE_LOOP_CALCULATE.preDirectCount=3
1.1.1.5.4 includeMethordsDirect
循环指令的前preDirectCount个指令中调用的指令的列表
# all methord direct:INVOKEVIRTUAL = 182;INVOKESPECIAL = 183;INVOKESTATIC = 184;INVOKEINTERFACE = 185;
PERFORMANCE_LOOP_CALCULATE.includeMethordsDirect=182,185
1.1.1.6 误报说明
1、可能会把循环体里面的计算当作条件判断的计算
如果preDirectCount参数的值过大
可能会把aa.size();当作循环计算
for(int i = 0,int len = list.size();i < len; i ++) {
aa.size();
}
----------------------river.liu 2010.4.17