JAVA关于方法调用的代码写法与性能问题

来源:互联网 发布:增值税地税所得税算法 编辑:程序博客网 时间:2024/05/16 05:25

    最近在做性能分析,使用ECLIPSE的TPTP做性能分析,虽然早前知道频繁的调用方法是比较耗性能的,毕竟需要维持一个调用栈,具体的理论已经模糊了,就拿实践来叙述一个问题吧。

    有如下代码

    

/** * get cache define list *  * @return List<Wt_cacheDomain> */public Map<String, Wt_cacheDomain> getCacheCfgMap() {if (cacheCfgMap == null) {cacheCfgMap = new HashMap<String, Wt_cacheDomain>();// DEBUGif (getWt_cacheList() != null && !getWt_cacheList().isEmpty()) {for (int i = 0; i < getWt_cacheList().size(); i++) {Wt_cacheDomain cacheDomain = (Wt_cacheDomain) getWt_cacheList().get(i);cacheCfgMap.put(cacheDomain.getCache_name(), cacheDomain);}}}return cacheCfgMap;}// 这里要从缓存取,不能实施从数据库加载public Wt_cacheDomain getCacheWithName(String cacheName) {//Map<String, Wt_cacheDomain> cacheConfigMap = getCacheCfgMap();if (cacheName == null || "".equals(cacheName)|| getCacheCfgMap() == null|| getCacheCfgMap().isEmpty()) {return null;} else {return getCacheCfgMap().get(cacheName);}}
    从上述的代码分析,在getCacheWithName()中我使用了三次的getCacheCfgMap(),这样在一个300次有对getCacheWithName()进行操作的程序中通过TPTP分析如下:


可以看到getCacheCfgMap()的平均执行性能为0.0001116秒

因此我修改代码后如下:

public Map<String, Wt_cacheDomain> getCacheCfgMap() {if (cacheCfgMap == null) {cacheCfgMap = new HashMap<String, Wt_cacheDomain>();if (getWt_cacheList() != null && !getWt_cacheList().isEmpty()) {for (int i = 0; i < getWt_cacheList().size(); i++) {Wt_cacheDomain cacheDomain = (Wt_cacheDomain) getWt_cacheList().get(i);cacheCfgMap.put(cacheDomain.getCache_name(), cacheDomain);}}}return cacheCfgMap;}public Wt_cacheDomain getCacheWithName(String cacheName) {//注意我这里用一个变量保存getCacheCfgMap()的值,这样这个方法就只有一次的调用.Map<String, Wt_cacheDomain> cacheConfigMap = getCacheCfgMap();if (cacheName == null || "".equals(cacheName)|| cacheConfigMap == null|| cacheConfigMap.isEmpty()) {return null;} else {return cacheConfigMap.get(cacheName);}}
注意注释的部分,这样getCacheWithName()就只调用了一次cacheConfigMap(),同样环境执行通过TPTP的分析如下:


不但Calls减少到了301次,而且平均执行时间也减少到0.000007次。

那么再继续修改代码如下为:

public Map<String, Wt_cacheDomain> getCacheCfgMap() {if (cacheCfgMap == null) {cacheCfgMap = new HashMap<String, Wt_cacheDomain>();if (getWt_cacheList() != null && !getWt_cacheList().isEmpty()) {for (int i = 0; i < getWt_cacheList().size(); i++) {Wt_cacheDomain cacheDomain = (Wt_cacheDomain) getWt_cacheList().get(i);cacheCfgMap.put(cacheDomain.getCache_name(), cacheDomain);}}}return cacheCfgMap;}public Wt_cacheDomain getCacheWithName(String cacheName) {//注意我这里用一个变量保存getCacheCfgMap()的值,这样这个方法就只有一次的调用.Map<String, Wt_cacheDomain> cacheConfigMap = getCacheCfgMap();cacheConfigMap = getCacheCfgMap();cacheConfigMap = getCacheCfgMap();cacheConfigMap = getCacheCfgMap();cacheConfigMap = getCacheCfgMap();cacheConfigMap = getCacheCfgMap();cacheConfigMap = getCacheCfgMap();if (cacheName == null || "".equals(cacheName)|| cacheConfigMap == null|| cacheConfigMap.isEmpty()) {return null;} else {return cacheConfigMap.get(cacheName);}}
cacheConfigMap = getCacheCfgMap();这里故意多调用了六次,那么是否性能会第一段代码还差呢?继续看TPTP结果


被调用了2107次,但是平均时间比第一段代码要好很多,说明对于无用的重复代码,java进行了必要的优化处理,但是仍旧比第二段代码性能差。

总结:

      1.如果一个方法多次调用其他方法并且其作用都是一样,获取值也同样的情况下,使用临时变量来保存调用后的值,在压力下不但因减少了调用次数而提高性能,还能提高被调用方法的性能。

      2.一个方法本身被调用的压力越大,它执行性能会越差,是否存在零界点,还未知。

原创粉丝点击