代码级的性能优化(二)

原创 2007年09月21日 23:27:00

      当数据量达到百万级的时候, 我们的项目遇到了一些问题, 一些报表速度慢的令人难以接受. 设计之初就考虑到报表速度的问题, 但是业务复杂, 需要从不同的数据源下获取信息并且加入若干项用户自定义公式的校验, 要命的是数十个这样的结果要显示在同一个表中. 一直没有更好的办法. 今天这个问题终于浮出了水面.

       深夜, 项目组的成员在宾馆的客房里讨论着解决办法. PSM要求大家全力优化自己的代码并且情绪极其激动; 几个成员认为瓶颈不在代码, 而在于数据库的优化和减少业务的复杂度, 用抽取少量数据来代替全量的比对; 其他人没有说话; 我在查看大家写的代码.

       减少业务复杂度是不可能的, 我们没有改变需求的权利, 而这也是个很合理的需求, 即使不合理也应该在项目前期提出; 抽取数据的方法也不可行, 我可不能忍受表格上的数据在没有更改数据库的时候每次都有变动; 数据库是要优化, 硬件也要提高, 但至少要在一周之后.

       大家的音调越来越高, 之后是半分钟的沉默. 我打破了这个沉默 :"我觉得我们的代码还有很多修改的余地, 单从修改代码结构就可以提高不少的性能, 比如减少函数的调用, 将循环赋值变成顺次硬编码赋值, 用位运算代替各别操作, 还有很多. 但是对一些代码的修改将降低程序的可读性..." 似乎我的话并没有引起多大重视, PSM只是重申了一便要优化代码.

      今天, 我在尝试一种可以提高效率的新方法时碰到了如下代码, 我原封不动的复制过来:

    private boolean oneLenCheck(Object[] pair) {
        
// 对 单个"运算符-数值"对进行判断
        
// 当有一个比较运算符匹配,即可返回结果
        boolean result = false;
        
int length = fieldContent.length();
        
if (pair[0].equals(">")) {
            
if (length > Integer.parseInt(pair[1].toString())) {
                result 
= true;
                
return true;
                
            } 
else {
                result 
= false;
                  
// System.out.println("length error:"+fieldContent);
                return false;
            }
        } 
else if (pair[0].equals("<")) {
            
if (length < Integer.parseInt(pair[1].toString())) {
                result 
= true;
                
return true;
            } 
else {
                result 
= false;
                
return false;
            }
        } 
else if (pair[0].equals("=")) {
            
if (length == Integer.parseInt(pair[1].toString())) {
                result 
= true;
                
return true;
            } 
else {
                result 
= false;
                
return false;
            }

        } 
else if (pair[0].equals(">=")) {
            
if (length >= Integer.parseInt(pair[1].toString())) {
                result 
= true;
                
return true;
            } 
else {
                result 
= false;
                
return false;
            }

        } 
else if (pair[0].equals("<=")) {
            
if (length <= Integer.parseInt(pair[1].toString())) {
                result 
= true;
                
return true;
            } 
else {
                result 
= false;
                
return false;
            }

        } 
else if (pair[0].equals("!=")) {
            
if (length != Integer.parseInt(pair[1].toString())) {
                result 
= true// 反向的,格外注意!
                return true;
            } 
else {
                result 
= false;
                
return false;
            }
        }
        
return result;
    }

 

       这段代码有些像刚刚开始学习程序设计的学生写的, 很多人都会毫不犹豫的说自己不会写这种蹩脚的代码, 是这样吗? 这段代码的作者是有一年多工作经验的人, 我相信他可以做出一些改正, 问题就在于很多人在敲击键盘的时候只是用手而没有用脑.

      这段代码有以下几个问题:

      1) 表达罗嗦, result 变量没有任何用处, 冗余的代码浪费了编译时间和硬盘空间, 并且降低了可读性;
     2) 两个if连接在一起, if后语句分配的是跳转的内存块, 无用的跳转占用了时间;
     3) Integer.parseInt(pair[1].toString()) 频繁使用, 如果平均步数为3, 则每次
oneLenCheck方法调用都需要做3次String 到 Integer的转换;
     4) 当数组下标频繁变换是, 指针片的切换比直接引用变量占用了更多的时间.

      我针对这些问题做了修改, 修改后的代码如下:

 

    private boolean oneLenCheck(Object[] pair) {
        
// 对 单个"运算符-数值"对进行判断
        
// 当有一个比较运算符匹配,即可返回结果

        
int length = fieldContent.length();
        
int parLength = Integer.parseInt(pair[1].toString());
        String symbol 
= pair[0+ "";
        
        
if (length > parLength && symbol.equals(">") {
            
return true;
        } 
else if (length < parLength && symbol.equals("<") {
            
return true;
        } 
else if ( length == parLength && symbol.equals("=") {
            
return true;
        } 
else if (length >= parLength && symbol.equals(">=") {
            
return true;
        } 
else if (length <= parLength && symbol.equals("<=")) {
            
return true;
        } 
else if (length != parLength && symbol.equals("!=") {
            
return true;
        }
        
        
return false;
    }

 

      当然, 修改后的代码也并非完美, 没有做到防御性编程, 执行Integer.parseInt(pair[1].toString())时可能抛出异常. 这是其他问题了, 在能够保证数据质量的时候可以放弃异常检测.

      性能提升: 进行1000次调用, 修改前的方法平均每次比修改后多0.00001秒, 则对于1,000,000条记录, 可以获得10秒的性能提升. 10秒钟, 哦, 我可以小心的倒杯热水.

 

35 个 Java开发代码性能优化总结

代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是,...
  • qq_22096121
  • qq_22096121
  • 2016年07月25日 09:32
  • 555

论代码级性能优化变迁之路(二)

本文是“论代码级性能优化变迁之路一”(http://www.jianshu.com/p/c4a748002e66) 的第二篇。在上一篇我们主要介绍了所遇到问题的五点,那么今天接下来讨论剩下的问题,我们...
  • u013970991
  • u013970991
  • 2016年07月28日 15:20
  • 3898

代码级的性能优化(一)

       对于性能的优化, Jon Bentley告诉我要分5个步骤:       1) 算法和数据结构的选择       2) 算法的优化       3) 数据结构的重组       4) 代...
  • sunbobosun5680
  • sunbobosun5680
  • 2007年08月17日 19:44
  • 615

不得不看的Java代码性能优化总结

前言 代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用...
  • Mr_Smile2014
  • Mr_Smile2014
  • 2015年11月30日 15:19
  • 6853

php 性能优化之php 语言级的性能优化一

php语言级的性能优化一
  • wjc19911118
  • wjc19911118
  • 2014年12月05日 02:45
  • 3887

Java代码性能优化6个原则

Java代码性能优化6个原则
  • wangyanming123
  • wangyanming123
  • 2016年04月07日 21:54
  • 756

php性能优化的几个方法

核心提示:本文主要讲述php性能优化的几个方法相关内容:PHP是一种在服务器端执行的脚本语言,它开发了世界上许多知名的网站,包括雅虎和Facebook等。下面介绍的几条PHP代码、性能优化的技巧供读者...
  • wylb226
  • wylb226
  • 2014年11月12日 17:31
  • 384

Java代码性能调优

一、类和对象使用技巧 1、尽量少用new生成新对象         用new创建类的实例时,构造雨数链中所有构造函数都会被自动调用,操作速度较慢。在某些时候可复用现有对象。比如在进行大量S...
  • linlzk
  • linlzk
  • 2014年12月25日 21:21
  • 8080

webpack前段构建性能优化策略小结

方案一、合理配置CommonsChunkPlugin    webpack的资源入口通常是以entry为单元进行编译提取,那么当多entry共存的时候,CommonsChunkPlugin的作用就会...
  • weifenwang
  • weifenwang
  • 2017年06月07日 16:31
  • 500

java性能优化笔记(三)java程序优化

程序代码优化要点: 字符串优化:分析String源码,了解String常用方法,使用StringBuffer、StringBuilder。 List、Map、Set优化:分析常用ArrayList...
  • kid_2412
  • kid_2412
  • 2016年09月13日 06:53
  • 3118
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:代码级的性能优化(二)
举报原因:
原因补充:

(最多只允许输入30个字)