代码级的性能优化(二)

原创 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秒钟, 哦, 我可以小心的倒杯热水.

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

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

本文是“论代码级性能优化变迁之路一”的第二篇。 在上一篇我们主要介绍了所遇到问题的五点,那么今天接下来讨论剩下的问题,我们先再回顾一下之前讨论的问题: 1、单台40TPS,加到4台服务器能...

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

架构师(JiaGouX) 我们都是架构师! 首先声明,本篇文章摘自公众号,仅供自己学习使用 一、前言 大家好,很久没有和大家一起讨论技术了,那么今天我将和大家一起探讨...

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

一、前言 大家好,很久没有和大家一起讨论技术了,那么今天我将和大家一起探讨我负责的某项目的性能变迁之路。 我们以前看到的很多架构变迁或者演进方面的文章大多都是针对架构方面的介绍,很少有...

Android性能优化之二 代码优化

Android性能优化之一 数据存储优化          Android性能优化之二 代码优化          Android性能优化之三 数据格式优化     ...

java代码性能的优化

Python 代码性能优化技巧

  • 2014-07-30 18:48
  • 278KB
  • 下载

Java 代码性能优化

文章来源:http://blog.csdn.net/richard_jason/article/details/53004974 代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地...

JAVA代码性能优化

  • 2017-07-10 17:26
  • 35KB
  • 下载

35 个 Java 代码性能优化总结

代码优化细节 1、尽量指定类、方法的final修饰符 带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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