StopWatch timer1 = new StopWatch();
timer1.start();
List<Map<String, Object>> rule = new ArrayList<>();
rule.add(businesstype);
RuleAnalysis.analysisObject(map, rule);
System.out.println("方法1计算出的值:"+map.get("agentprofitmargin"));
timer1.stop();
long totalTimeMillis1 = timer1.getTotalTimeMillis();
System.out.println("方法1运行1次用时:"+totalTimeMillis1);
StopWatch timer2 = new StopWatch();
timer2.start();
double aDouble = CalculationRules.analysisRules(abc, map);
timer2.stop();
System.out.println("方法2计算出的值:"+aDouble);
long totalTimeMillis2 = timer2.getTotalTimeMillis();
System.out.println("方法2运行1次用时:"+totalTimeMillis2);
运行一次的结果:
方法1计算出的值:0.9000
方法1运行1次用时:22
方法2计算出的值:0.9
方法2运行1次用时:69
StopWatch timer1 = new StopWatch();
timer1.start();
List<Map<String, Object>> rule = new ArrayList<>();
rule.add(businesstype);
for(int i = 0;i<10000;i++){
RuleAnalysis.analysisObject(map, rule);
}
timer1.stop();
long totalTimeMillis1 = timer1.getTotalTimeMillis();
double avg1 = totalTimeMillis1/10000.0;
System.out.println("方法1运行10000次用时:"+totalTimeMillis1+",平均用时:"+avg1);
StopWatch timer2 = new StopWatch();
timer2.start();
for(int i = 0;i<10000;i++){
CalculationRules.analysisRules(abc, map);
}
timer2.stop();
long totalTimeMillis2 = timer2.getTotalTimeMillis();
double avg2 = totalTimeMillis2/10000.0;
System.out.println("方法2运行10000次用时:"+totalTimeMillis2+",平均用时:"+avg2);
运行10000次结果:
方法1运行10000次用时:7036,平均用时:0.7036
方法2运行10000次用时:350,平均用时:0.035
运行5次结果:
方法1运行5次用时:48,平均用时:9.6
方法2运行5次用时:84,平均用时:16.8
运行10次结果:
方法1运行10次用时:111,平均用时:11.1
方法2运行10次用时:98,平均用时:9.8
运行100次结果:
方法1运行100次用时:388,平均用时:3.88
方法2运行100次用时:124,平均用时:1.24
方法1运行200次用时:636,平均用时:3.18
方法2运行200次用时:125,平均用时:0.625
运行1000次结果:
方法1运行1000次用时:2519,平均用时:2.519
方法2运行1000次用时:394,平均用时:0.394
虽然两个方法执行次数越多平均耗时均变短,但是很明显方法2的平均耗时缩短的速度更快。
执行10次之后方法2的效率就超过了方法1。
方法1和方法2的实现方式不一样,特殊之处在于
方法1运用了递归和反射
方法2使用了栈
分析:
一般情况下递归、反射不会被jvm用内联优化,而且反射效率会比较低。
方法2在执行次数过多变为热点函数过后会被优化,JVM默认调用超过100次就会认为是热点函数从而内联优化,可以看到函数执行100次和执行200次的总时间只相差1毫秒。可以认为是被优化了。而方法一调用100次和调用200次所耗时为一倍的关系。自然能知道没有被优化。
至于执行次数少时为什么方法1会更快 大概就在于方法2创建对象比较耗时(猜测)。