Dict.CN 在线词典, 英语学习, 在线翻译

学海苦作舟,书山勤为径

留下点回忆

常用链接

统计

积分与排名

Denoise

English study

Web技术

数据压缩

一些连接

最新评论

一段代码的几种写法-怎么样写好的代码

 

程序员当然要说代码了,代码是程序员的一切,离了代码说其他都是假的,我这里从一段代码开始。

 

    int c=0, n=0,nDiff=0;
    
int height = m_imgHeight;//image height
    LPBYTE lpDsp 
= pSampling;
    jp2_int16 
*sp, val;
    LPBYTE dest;
    
//m_imgWidth-image width

    nDiff 
= m_lineBytes - m_imgWidth*3;
    
while (height--) {
        
for (c=0; c<THREE_COMPONENT; c++) {
            dest 
= lpDsp+c;
            sp 
= m_lines[c].m_pBuf;
            
for (n=m_imgWidth; n>0; n--, sp++, dest+=THREE_COMPONENT) {
                
*sp += 2;//virtual option
                    ……
                
*dest = *sp;
            }
        }

        
/*
        
If the bytes isn't 4-bytes multiple, 1-3 bytes will not be 
        initialized. So these bytes should be initialized as 0
        
*/
        
if(nDiff){
            dest 
-= 2;
            
for(n = nDiff;n>0;n--){
                
*dest = 0;
                dest
++;
            }
        }

        lpDsp 
+= m_lineBytes;
    }

 

这段代码的目的是一个与图形相关的操作,这里省略了许多代码,所以不可能编译;其基本的含义是从一个缓冲区复制到目标缓冲区pSampling。其中m_imgWidthm_imgHeight表示图象的宽度和高度,m_lineBytes表示4个字节对齐的一行像素的字节数。

我们知道BMP文件的像素要求每行的最终字节数必须是4个倍数。如果图象宽度是4的倍数,不用仇是没有问题的;如果不是4的倍数,例如:129,而且每个像素一个字节,那么最终存储的长度是132个字节,但后面的几个字节如果不填充是未知的内容。上面if(nDiff){后面的就是为了填充这些多余的字节。

我的一个朋友认为这样写更有效一点:

 

            dest -= 2;
            
for(n = nDiff;n>0;n--){
                
*dest = 0;
                dest
++;
            }

他的分析是:如果66%的机会nDiff不是0,这个代码效率更高。

来看一下两种写法的不同:

第一种写法是:不管3721,都判断一下;如果nDiff不为0,需要至少3个指令:判断//判断。

第二种写法是:不判断,先减,然后通过for循环来判断。对于nDiff0不为0,都是两个指令:减/判断。

但如果多余66%的机会(比如70%)nDiff不为0,第一种写法需要的平均指令数为:

70%*3+30%*1 = 2.4

第二种写法的平均指令数为:

70%*2+30%*2 = 2

可见第二种写法的好处可以体现在:

1. 代码简洁

2. 效率更高

 

但我发现代码中很少的机会nDiff不为0,这位老兄又立刻想到了另一种写法:

  

        if(nDiff){
            dest 
-= 2;
            
do{
                
*dest = 0;
                dest
++;
            } 
while(nDiff--);
        }

再来看一下这种写法的特点,假设30%的机会nDiff不为0

原来写法的指令数为:

70%*1+30%*3 = 1.6

上面写法的指令数为:

70%*1+30%*2 = 1.3

因为第一次不需要判断;当然后面的循环都是一样的。

 

从这件事情的本身我们甚至可以说是吹毛求茨,而从效率上来说这个代码提高的并不是很多。但我想说的不是这些,而是故事说明的写这个代码的时候作者在想些什么,我想至少是这样的:

1. 写出简洁的代码。第二种写法明显简洁。

2. 写出最高效的代码,即使是CPU很快的今天。如果上面的代码在一个循环的内部,效率高低很快就体现出来。

3. 深入的思考和比较。计算条件成立的概率,至少应该对代码在什么情况下运行很了解。


4. 写好代码的精神。

posted on 2007-07-06 12:44 笨笨 阅读(1682) 评论(11)  编辑 收藏 引用 所属分类: 编码

评论

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 15:47 SuperPlayeR

不讲效率的话,memset(dest, 0, nDiff);也可以

恕我直言,我个人认为在这样的小地方求效率的提高,不如把代码写的更容易让人看懂。《Unix编程艺术》中似乎有对于这种“优化”做过探讨,我比较赞成书中作者的观点。  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 16:11 SmartPtr

我有两点想法, 一是在性能不是关键因素的程序中代码的可读性重于效率;二是代码效率优化应该针对关键的瓶颈。 当然, 博主的一些思路也是值得讨论的  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 17:32 夏夏

怎麽办,一点点都看不懂~~~  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 21:22 AlanTop

*dest = 0;
dest++;

上面这两行代码,可以写成

*dest++ = 0;

  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 21:41 笨笨

@SuperPlayeR
你说的很对,如果不讲效率代码写的容易懂是关键.但简洁的代码也是让人懂的一个方面.另外实际上我在讨论的时候也很关注效率的问题.
  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 21:41 笨笨

@AlanTop
很好,你的这种做法很正确.  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 22:10 sy555

你说的很对,
-------------------------------------------------
http://www.sy555.com  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码[未登录] 2007-07-06 22:11 QQ

<p><a href="/"";http://www.qq128.net/">QQ信息网</a></p>  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-06 22:54 pass86

支持第二种。  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-09 22:46 Jerry.Yu

why not initialize dest buffer at the beginning, such as using
memset(...) ? If I am right, the size of dest buffer can be work out the beginning.
...

also, the code segment like
for(n ... ; n++) can be write as for(n....; ++n) .. would be better for compiler....



  回复  更多评论   

# re: 一段代码的几种写法-怎么样写好的代码 2007-07-10 09:01 笨笨

@Jerry.Yu
memset is high price if you just set several bytes as zero, so from performancd view, memset isn't always good.

You don't understand the problem really yet. The write style just to avoid two check condition words
  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理