`
mingren135
  • 浏览: 69127 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

开发中的案例分析-他山之石

 
阅读更多

案例1:输出debug信息需要加enable判断

 

log.debug("userId:"+ user.getId())//-->
if(log.isDebugEnable()){
    log.debug("userId:"+ user.getId())
}

 分析:1、不加enable判断,括号中的字符串相加会产生中间字符,大量调用时创建和销毁的数量非常庞大,会造成gc频繁执行,进而影响性能。2、线上日志一般不会是debug,因此执行字符串拼接是无意义的运算。根据log优先级,对error、warn可以不用判断

 

案例2:遍历map时,特别是数据量较大时不要使用get(key)取值

for(Iterator<String> ite = map.keySet().iterator(); ite.hasNext();){
    String key = ite.next();
    String value = map.get(key);
}
-->
for(Iterator<Entry<String,String>> ite = map.entrySet().iterator(); ite.hasNext();){
    Entry<String,String> entry = (Entry<String,String>) ite.next();
    String key = entry.getKey();
    String value = entry.getValue();
}

 分析:Map类的get(key)方法会进行两次hashCode的运算,造成效率低

public V get(Object paramObject)
  {
    if (paramObject == null)
      return getForNullKey();
    int i = hash(paramObject.hashCode());
    for (Entry localEntry = this.table[indexFor(i, this.table.length)]; 
      localEntry != null; 
      localEntry = localEntry.next)
    {
      Object localObject;
      if ((localEntry.hash == i) && (((localObject = localEntry.key) == paramObject) || (paramObject.equals(localObject))))
        return localEntry.value;
    }
    return null;
  }

 

 案例3: Java5的正则表达式没有执行事实上perl标准,也有有若干缺陷,一是可能会导致JVM的崩溃,二是在递归处理上性能低下,使用时也需要预编译。

Pattern p = Pattern.compile("^[a-zA-Z]+[a-zA-Z0-9]+");  
Matcher m = p.matcher("12aa");
if(m.matches()){...}
->
private static final Pattern p = Pattern.compile("^[a-zA-Z0-9]+");
or
private static final Pattern p = new Perl5Compiler().compile("^[a-zA-Z0-9]+$", '''Perl5Compiler.READ_ONLY_MASK''');
//由于Pattern本身不是线程安全的,只有加了READ_ONLY_MASK的编译参数才能用于共享使用,否则会出现并发访问的问题,导致错误结果
PatternMatcher matcher = new Perl5Matcher();
if(matcher.matches("123", p)){...}

分析:建议使用oro库处理RegExp,表达式一定要求是预先编译的,编译过程是非常消耗性能的。我们经常用的String.split()方法里的实现:Pattern.compile(paramString).split(this, paramInt),可以看出性能也是不高的,最好使用pattern.split(str)

.  匹配任意一个字符 $ 匹配一行的结尾 ^ 匹配一行的开头(在[]里面表示否定) 
{} 定义了一个范围  [] 定义了一个字符类 () 定义了一个组 
*前面出现0次以上   + 前面匹配一次以上 ?前面出现0次或一次   
\ 后面的字符不会看作metacharacter  \w 字母数字下划线 \W 非字母数字下划线 
\d 单个数字 \D单个非数字 | 或,二者之一 &&与操作符 \b单词边界 

 

 案例5:serialVersionUID 来解决软件兼容性的问题,即在版本升级时(对象新增或减少字段)反序列化仍保持对象的唯一性。有些情况不能更改 serialVersionUID ,比如分布式环境下,如果要修改,只能关联系统都暂停服务,发布完后再对外统一提供服务。有些情况必须修改serialVersionUID ,比如缓存中的数据,新增了字段,但缓存中的数据还是老的数据,不修改serialVersionUID ,反序列化回来会缺少新增的字段值,这时修改serialVersionUID 值则会在反序列化时报错,重新put新的缓存数据。

private static final long serialVersionUID = 7311398892155614476L;

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics