[TL]{技术}有些代码习惯,是交给编译器?还是自己就写的好一些。选择什么样的习惯?

38 views
Skip to first unread message

LeeoNix

unread,
Apr 28, 2009, 2:29:06 PM4/28/09
to TopLanguage
简单的for循环作为例子:

vector<int> ivec;
for(vector<int>::iterator it = ivec.begin(); it != ivec.end(); it++)

知道一些STL基础的都知道这个其实并不是最合理的方式。

for(vector<int>::iterator it = ivec.begin(), last = ivec.end(); it != last; ++it)

区别就在于保存end()迭代器,和++的前缀式和后缀式。
而现在编译器优化功能很是强大,将后缀式优化为前缀式。end()这个,也会优化掉。

可以说,现在编译器已经很智能了。

虽然最被推荐的方式还是用for_each,不过我还是用的很少。

使用STL的迭代器的时候,我还是会选择上面我举的例子的后者。虽然代码量稍大,但胜在我可以有个好习惯。

哪怕写for(int i = 0; i < size; ++i) 我都是这么写的。

我不知道大家是怎么看待这种编译器优化,我认为好的习惯更重要一些。

看看大家的视角怎么看待这个事情。

Weiyu Yi

unread,
Apr 28, 2009, 4:46:45 PM4/28/09
to pon...@googlegroups.com
这2种方式,主要区别还是在于容器vector可能会变化吧

如果vector变大了,那么第2种方式就不是你希望它做的事情了

很少回复,希望大家指教

2009/4/28 LeeoNix <leeo...@gmail.com>

wing

unread,
Apr 28, 2009, 9:09:52 PM4/28/09
to pon...@googlegroups.com
我觉得好的习惯很重要,依赖编译器,一旦换一个编译器,会带来不可预测的事情,不过回到这个例子,我更喜欢for_each。^_^


--
wing
wing9...@gmail.com
Hope is a good thing, maybe the best of things.

alai

unread,
Apr 28, 2009, 10:45:32 PM4/28/09
to pon...@googlegroups.com
1.代码是写给人看的,不是写给编译器看的;
2.象STL标准容器的end()函数都会是inline的,不存在LZ说的效率问题;
3.无论从易读性或效率方面,for_each都更好。

2009/4/29 wing <wing9...@gmail.com>

Ian Young, Yingcai

unread,
Apr 28, 2009, 3:06:50 PM4/28/09
to pon...@googlegroups.com
就这个问题本身来说,现代的编译器是一定能优化的,如果不能,换编译器吧。

既然效率不是问题,那到底什么风格就因人而异,保持一致就行。

不过个人还是倾向写


for(vector<int>::iterator it = ivec.begin(), last = ivec.end(); it != last; ++it)


如果不打算用上boost.lambda,for_each确实很不方便。

编译器支持snippits展开的话,可以写个模板。因为不管什么方式,都很容易出错,而且每次敲那么一大堆也很烦。

Boost 用宏实现了个 BOOST_FOREACH , 比较方便,

e.g. 把matrix所有元素增一

std::vector<std::vector<int> > matrix_int;
BOOST_FOREACH( std::vector<int> & row, matrix_int )
    BOOST_FOREACH( int & i, row )
        ++i;

张慧聪

unread,
Apr 28, 2009, 11:15:56 PM4/28/09
to pon...@googlegroups.com
想丐了一本书,主名忘了,附名是“用级语言思考,编写高级语言代码”,是一套书的第二本。作者是写《汇编语言编程艺术》的,同时也是HLA(High Level Assembler)汇编器的作者



居振梁

unread,
Apr 28, 2009, 11:46:26 PM4/28/09
to pon...@googlegroups.com
《深入理解计算机》系列。

2009/4/29 张慧聪 <zhcfr...@gmail.com>

想丐了一本书,主名忘了,附名是“用级语言思考,编写高级语言代码”,是一套书的第二本。作者是写《汇编语言编程艺术》的,同时也是HLA(High Level Assembler)汇编器的作者



--
自学走了不少弯路,更浪费了太多的时间,寻找良师益友。
追求黑客精神和清心寡欲的心态。
http://wargrey.yo2.cn
http://wargrey.blogspot.com
主要兴趣:Unix/GNU Linux、人工智能、移动计算、虚拟化
其他兴趣:心理学、自然科学、数学、武术、自然语言

Kenny Yuan

unread,
Apr 29, 2009, 12:29:51 AM4/29/09
to pon...@googlegroups.com
Just hand it over to the profiler

Fei Yan

unread,
Apr 29, 2009, 12:31:58 AM4/29/09
to pon...@googlegroups.com

2009/4/29 alai <ala...@gmail.com>
1.代码是写给人看的,不是写给编译器看的;
2.象STL标准容器的end()函数都会是inline的,不存在LZ说的效率问题;

一般情况,这个确实都是被优化掉的,而且多定义一个变量就多了个记忆负担,因此不觉得这个会增加易读性。
 

3.无论从易读性或效率方面,for_each都更好。

for_each会影响局部性,因为还要在其它地方定义一个functor,工业级代码(商业软件)中,我见到的用for_each的很少(开源项目倒是不少);即使有人用,被接受度也不广。
 

LeeoNix

unread,
Apr 29, 2009, 2:28:59 AM4/29/09
to pon...@googlegroups.com
呵呵,看来大家都接受好习惯。

我一直提到的那个,和我经常讨论问题的同事,

在我和他上一次工作里,大概是3年前,我就给他说过end()还有前缀++的问题。

当时他接受了我的建议,并且查找都修改掉了。

昨天向我提到编译器优化的事情,就说起这个,

不过他说,他还是会自己写代码优化,而不会交给编译器,主要是能养成一个好习惯,

因为有时候,会被编译器宠坏。

我也觉的,有个好习惯貌似更为重要一些。

2009/4/29 Fei Yan <skyscr...@gmail.com>

Kenny Yuan

unread,
Apr 29, 2009, 2:37:24 AM4/29/09
to pon...@googlegroups.com
商业级和工业级是不同的级别啦……

2009/4/29 Fei Yan <skyscr...@gmail.com>



--
Kenny Yuan
C++, UI, LISP, MMA, Psychology and Automobile.
BLOG: CS巴别塔(Computer Science Babel)
URL: http://blog.csdn.net/yuankaining/


James Z.M. GAO

unread,
Apr 29, 2009, 4:13:52 AM4/29/09
to pon...@googlegroups.com
还有一个类似的优化与习惯的选择, 就是乘除法优化, 是否用位运算代替乘除法,
是否用乘法代替除法, etc, 现在这些大部分都能被编译器或者硬件优化了,
不过好习惯似乎总是被推荐.

On Wed, 29 Apr 2009, LeeoNix wrote:

> 呵呵,看来大家都接受好习惯。
>
> 我一直提到的那个,和我经常讨论问题的同事,
>
> 在我和他上一次工作里,大概是3年前,我就给他说过end()还有前缀++的问题。
>
> 当时他接受了我的建议,并且查找都修改掉了。
>
> 昨天向我提到编译器优化的事情,就说起这个,
>
> 不过他说,他还是会自己写代码优化,而不会交给编译器,主要是能养成一个好习惯

??
>
> ??因为有时候,会被编译器宠坏。


>
> 我也觉的,有个好习惯貌似更为重要一些。
>
> 2009/4/29 Fei Yan <skyscr...@gmail.com>
>
> 2009/4/29 alai <ala...@gmail.com>
> 1.代码是写给人看的,不是写给编译器看的;
> 2.象STL标准容器的end()函数都会是inline的,不存在LZ说的效率问题;
>
>
> 一般情况,这个确实都是被优化掉的,而且多定义一个变量就多了个记忆负担,因此

?? ??觉得这个会增加易读性。


>  
>
> 3.无论从易读性或效率方面,for_each都更好。
>
>
> for_each会影响局部性,因为还要在其它地方定义一个functor,工业级代码(商业软

?? ??)中,我见到的用for_each的很少(开源项目倒是不少);即使有人用,被接受度也
?? ??广。


>  
>
>
> 2009/4/29 wing <wing9...@gmail.com>
>
> 我觉得好的习惯很重要,依赖编译器,一旦换一个编译器,会带来不可预测的事情,

?? ??过回到这个例子,我更喜欢for_each。^_^

LeeoNix

unread,
Apr 29, 2009, 4:05:36 AM4/29/09
to pon...@googlegroups.com
James Z.M. GAO 兄的帖子总是很有价值,
不过邮件客户端的引用有点问题,弄得帖有点长……

2009/4/29 James Z.M. GAO <gao...@gmail.com>

James Z.M. GAO

unread,
Apr 29, 2009, 4:41:53 AM4/29/09
to pon...@googlegroups.com
to LeeNix

多些夸奖, 说会的, 学不会的, 仅此而已, 呵呵

关于回复格式, 我用alpine作为客户端,
在回复时候使用其默认的全文引用文本格式,
我刚才看了, 这个格式在网页下浏览不能自动折叠, 以后注意,
会把不用的引用文字删掉~
我对apline的配置研究的还不透, 应该有自动调整引用格式及引用行数限制的功能,
有了解的指教一下阿, 呵呵~

hongquan yin

unread,
Apr 29, 2009, 4:43:13 AM4/29/09
to pon...@googlegroups.com
更正一下,如果vector的尺寸变化了,那么其上所有的迭代器都会失效。
我倾向于好的编码习惯,因为这是基于自己对计算机的理解。随着自己对计算机系统理解到深入,编写的代码会越来越优秀。如果依靠某个编译器或者库,会把自己宠坏,也不利于自己的提高。

2009/4/29 Weiyu Yi <inw...@googlemail.com>

空气

unread,
Apr 29, 2009, 7:19:08 AM4/29/09
to TopLanguage
《深入理解计算机系统》里面说过,类似于
for (int i = 0; i < function(); i++)
这种东西编译器是不会优化成
size = function();
for (int i = 0; i < size; i++)

原因在与function()里面可能会执行一些影响其他东西的操作,比如对一个全局变量递增。
这样“优化之后”这个全局变量就不会每次递增。

编译器优化的大前提是不能改变代码原本的语义。

LeeoNix

unread,
Apr 29, 2009, 8:04:01 AM4/29/09
to pon...@googlegroups.com
你错了,是会优化成这样的,不信你可以看反汇编。

这个是一个事实。

编译器会判断循环体的。

2009/4/29 空气 <lct...@gmail.com>

xuzi...@gmail.com

unread,
Apr 29, 2009, 9:47:08 AM4/29/09
to pon...@googlegroups.com
在2009-04-29的邮件[[TL] Re: {技术}有些代码习惯,是交给编译器?还是自己就写的好一些。选择什么样的习惯?]中写到:
leeonixar> 你错了,是会优化成这样的,不信你可以看反汇编。
leeonixar>
leeonixar> 这个是一个事实。
leeonixar>
leeonixar> 编译器会判断循环体的。
我怎么觉得这是一个特例?
size() 在vector里面是inline的只是返回一个内部的size_t而已,所以能够被内联,导致
看起来被优化掉了一样,要是如下的代码,我相信是不会被优化掉的:
for(size_t i=0;i<strlen(str);++i) {
...
}
顺手测试了一把,VS7.1

#include <iostream>
#include <string.h>
size_t len(const char* str)
{
std::cout << "call len\n";
return strlen(str);
}
int main(int argc, char *argv[])
{
const char* const str = "Hello";
size_t count = 0;
for(size_t i=0;i<len(str);++i){
++count;
}
std::cout << count;
return 0;
}


cl -EHsc -O2 1.cpp

/out:1.exe
1.obj
call len
call len
call len
call len
call len
call len
5
--
唉,啥都不行,只能回去扣腚

Fei Yan

unread,
Apr 29, 2009, 10:21:00 AM4/29/09
to pon...@googlegroups.com
尽信书不如无书,呵呵

2009/4/29 空气 <lct...@gmail.com>

LeeoNix

unread,
Apr 29, 2009, 10:35:11 AM4/29/09
to pon...@googlegroups.com
唉……

不要歪曲这句话,拿这句话出来干嘛?

孟子的“书”是《尚书》,是特指这本书。

2009/4/29 Fei Yan <skyscr...@gmail.com>

Jeffrey Zhao

unread,
Apr 29, 2009, 10:41:23 AM4/29/09
to pon...@googlegroups.com
这是句吵架专用语。通常用于回应别人从书中找出的示例来证明问题。此句一出,可谓无往而不胜。
 

Eric.Wang

unread,
Apr 29, 2009, 12:34:02 PM4/29/09
to TopLanguage
我倾向于

vector<int> ivec;
for(vector<int>::iterator it = ivec.begin(); it != ivec.end(); it++)

因为简洁明快,所见即所得。

优化 is another case。

一个程序里面,其实大部分代码都是不用优化的。为了这些不用优化的地方付出额外代价,其实就是损失。

在需要优化的地方做优化。不需要优化的地方,就写得简洁明快一点,好维护。

这是我的观点。


On 4月29日, 上午2时29分, LeeoNix <leeoni...@gmail.com> wrote:

学宁

unread,
Apr 29, 2009, 1:34:27 AM4/29/09
to pon...@googlegroups.com
我发表几个比较肤浅的看法吧

我现在是个还没毕业的本科生,对于stl不熟悉,由于从c语言迈入C++的大门的,所以对c的语法相对使用比较多,所以“习惯性”的使用c的风格,而不是for_each等比较优雅的实现

其实我想想,这其实不是习惯,而是由于对stl不熟悉,一种自我保护的举动,因为很少甚至没写过for_each,所以不敢尝试的去用这种更简单的语句来实现。一直不敢就成了习惯了。如果你最初是就是习惯了for_each的写法,当你用for的时候,估计也会考虑这段代码是否能按自己的计划来运行呢?

我觉得我选择c++的原因之一就是 他的兼容并包,我可以在c++使用我最熟悉的风格来编程,无论是结构化 还是OO或者是GP,而到机器语言这一层面,有强大的编译器来支持,这可以让你省很多心力的。

我觉得还是选择自己最“习惯”的办法,c++程序员不仅仅应该考虑程序的效率,也要兼顾考虑开发的效率。

2009/4/29 Fei Yan <skyscr...@gmail.com>

李平新

unread,
Apr 29, 2009, 3:11:55 AM4/29/09
to pon...@googlegroups.com
”好脑子,不如一个烂笔头“
自己优化吧,对程序效率虽没什么,但对个人,逻辑,推理,修养很好

2009/4/29 Kenny Yuan <yuank...@gmail.com>

Ian Young, Yingcai

unread,
Apr 29, 2009, 12:37:32 PM4/29/09
to pon...@googlegroups.com
优化的前提当然是不改变程序行为。这样需要你的len的调用不会影响到程序其它地方,不能改全局变量,不能IO,等等。简单点说,就是需要调一次和调N次效果是一样的

如果你的len把那句io去掉,连len者优化掉了

下面是用gcc -O2 -S test.cpp 产生的汇编中main函数的定义,可以看到,压根就没循环,没len调用,整个程序相当于 main() {std::cout << 5; return 0;}

main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl    -4(%ecx)
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ecx    // 到这都在设置栈
    subl    $20, %esp // 在栈上分配空间
    movl    $5, 4(%esp) // 把常量5入栈
    movl    $_ZSt4cout, (%esp) // 把cout的this指针入栈
    call    _ZNSo9_M_insertImEERSoT_ // 调用函数进行输出
    addl    $20, %esp // 从这开始恢复栈
    xorl    %eax, %eax
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret

Sincerely, Ian Yang

Sent from Shanghai, 31, China

Jack.Chu

unread,
Apr 29, 2009, 9:27:37 PM4/29/09
to TopLanguage
这个才是真知灼见。

xpol

unread,
Apr 30, 2009, 10:24:02 AM4/30/09
to TopLanguage

> 哪怕写for(int i = 0; i < size; ++i) 我都是这么写的。
我们是同类啊,楼主。

不过如果用到是stl容器的话,你会发现for_each更好些。
当然,目前的问题是C++对Lamda的支持不好的情况下,for_each的最后一个参数还是不太方便啊。

wanng fenng

unread,
May 1, 2009, 12:41:08 AM5/1/09
to pon...@googlegroups.com


2009/4/30 xpol <xpo...@gmail.com>

不过如果用到是stl容器的话,你会发现for_each更好些。
当然,目前的问题是C++对Lamda的支持不好的情况下,for_each的最后一个参数还是不太方便啊。

如果是两个或者多个容器对象操作,似乎很难操作
比如matlab中可以这样写:
arr1 = (arr1 + arr2 * arr3)
在c++要么自己写个模板函数,要么就得for循环了

Fei Yan

unread,
May 1, 2009, 1:40:47 AM5/1/09
to pon...@googlegroups.com

2009/4/29 学宁 <xnin...@gmail.com>

我发表几个比较肤浅的看法吧

我现在是个还没毕业的本科生,对于stl不熟悉,由于从c语言迈入C++的大门的,所以对c的语法相对使用比较多,所以
 
“习惯性”的使用c的风格,而不是for_each等比较优雅的实现


大部分人都是这么干的,不仅是熟悉c++不久的人,很多号称是写了N年c++代码的人(我就见过不少)见到for_each也会一顿臭骂,然后花半天去理解。
程序员的水平是参差不齐的,但大家还是得写作。

 


其实我想想,这其实不是习惯,而是由于对stl不熟悉,一种自我保护的举动,因为很少甚至没写过for_each,所以不敢尝试的去用这种更简单的语句来实现。一直不敢就成了习惯了。如果你最初是就是习惯了for_each的写法,当你用for的时候,估计也会考虑这段代码是否能按自己的计划来运行呢?

我觉得我选择c++的原因之一就是 他的兼容并包,我可以在c++使用我最熟悉的风格来编程,无论是结构化 还是OO或者是GP,而到机器语言这一层面,有强大的编译器来支持,这可以让你省很多心力的。

我觉得还是选择自己最“习惯”的办法,
c++程序员不仅仅应该考虑程序的效率,也要兼顾考虑开发的效率。

 这个应该也是一个很重要的因素,实际影响依赖于Team内部的个成员水平差异。
 

Fei Yan

unread,
May 1, 2009, 1:46:43 AM5/1/09
to pon...@googlegroups.com
绝没有吵架的意思,只是说书本知识很多都是纯理论、死板的,实际情况可能未必是那么回事。

按照大众化的理解,“尽信书不如无书”是被泛化了的,是个统称,没多少人会纠结于它的出处和指代。


2009/4/29 Jeffrey Zhao <je...@live.com>

Eric.Wang

unread,
May 1, 2009, 6:13:43 AM5/1/09
to TopLanguage
"依赖于Team内部的个成员水平差异",我对这个说法不太认可。
并不是知道for_each就应该用for_each,我推崇的是"知其雄而守其雌",即使有能力把C++代码写得落英缤纷,也应该从实用的角度出发,
写出朴实好用的代码。
是写boost风格的代码还是写C风格的代码,并不是依赖于水平,而是依赖于需求。什么风格的代码更适合这个项目,就应该采用什么风格的代码。通常来
说,朴实无华的代码是更好维护的。

能够放弃卖弄的心理,踏实的设计和写出好的代码、能够正确工作的代码、易于维护和扩展的代码,我认为才是程序员成熟的标志。


On 5月1日, 下午1时40分, Fei Yan <skyscribe...@gmail.com> wrote:
> 2009/4/29 学宁 <xning...@gmail.com>


>
> > 我发表几个比较肤浅的看法吧
>
> > 我现在是个还没毕业的本科生,对于stl不熟悉,由于从c语言迈入C++的大门的,所以对c的语法相对使用比较多,所以
> > "习惯性"的使用c的风格,而不是for_each等比较优雅的实现
>
> 大部分人都是这么干的,不仅是熟悉c++不久的人,很多号称是写了N年c++代码的人(我就见过不少)见到for_each也会一顿臭骂,然后花半天去理解。
> 程序员的水平是参差不齐的,但大家还是得写作。
>
>
>
> > 其实我想想,这其实不是习惯,而是由于对stl不熟悉,一种自我保护的举动,因为很少甚至没写过for_each,所以不敢尝试的去用这种更简单的语句来实现。一直不敢就成了习惯了。如果你最初是就是习惯了for_each的写法,当你用for的时候,估计也会考虑这段代码是否能按自己的计划来运行呢?
>
> > 我觉得我选择c++的原因之一就是 他的兼容并包,我可以在c++使用我最熟悉的风格来编程,无论是结构化
> > 还是OO或者是GP,而到机器语言这一层面,有强大的编译器来支持,这可以让你省很多心力的。
>
> > 我觉得还是选择自己最"习惯"的办法,
>
> c++程序员不仅仅应该考虑程序的效率,也要兼顾考虑开发的效率。
>
>
>
> 这个应该也是一个很重要的因素,实际影响依赖于Team内部的个成员水平差异。
>
>
>

> > 2009/4/29 Fei Yan <skyscribe...@gmail.com>


>
> >> 2009/4/29 alai <ala...@gmail.com>
>
> >>> 1.代码是写给人看的,不是写给编译器看的;
> >>> 2.象STL标准容器的end()函数都会是inline的,不存在LZ说的效率问题;
>
> >> 一般情况,这个确实都是被优化掉的,而且多定义一个变量就多了个记忆负担,因此不觉得这个会增加易读性。
>
> >>> 3.无论从易读性或效率方面,for_each都更好。
>
> >> for_each会影响局部性,因为还要在其它地方定义一个functor,工业级代码(商业软件)中,我见到的用for_each的很少(开源项目倒是不少);即使有人用,被接受度也不广。
>

> >>> 2009/4/29 wing <wing922w...@gmail.com>


>
> >>> 我觉得好的习惯很重要,依赖编译器,一旦换一个编译器,会带来不可预测的事情,不过回到这个例子,我更喜欢for_each。^_^
>
> >>>> --
> >>>> wing

> >>>> wing922w...@gmail.com

Fei Yan

unread,
May 1, 2009, 7:38:48 AM5/1/09
to pon...@googlegroups.com


2009/5/1 Eric.Wang <wangsh...@gmail.com>

"依赖于Team内部的个成员水平差异",我对这个说法不太认可。
并不是知道for_each就应该用for_each,我推崇的是"知其雄而守其雌",即使有能力把C++代码写得落英缤纷,也应该从实用的角度出发,
写出朴实好用的代码。

同意这一点说法;朴实的代码很多情况下是最好的,尤其是对于生命周期很长的庞大项目。

现实情况很多是,实际写代码、维护代码的人水平差异会影响到需求的实施,这种情况下,coders能接受什么样的代码就比较重要了。

我的看法是,大部分情况不是因为朴实的代码比所谓的落英缤纷、花里胡哨的代码(表达力更强、更短)更能合乎需求,而是因为很多人无法接受而已。

对于代码实现而言,我个人认为大部分情况下受外部需求的限制并不是很大。
你完全可以用花哨的代码写出满足C ABI接口的实现,正如Willson的Extended STL.
 

是写boost风格的代码还是写C风格的代码,并不是依赖于水平,而是依赖于需求。
什么风格的代码更适合这个项目,就应该采用什么风格的代码。通常来

这个在实际实施中很难吧,有点理想化了。譬如你认为boost风格的代码更合乎需求(如果没有这样的情况存在,那么boost也不会这么被广泛应用),但下边的人都抵制一切和模板沾边儿的东西,结果会如何?

 

chaoyan ma

unread,
May 1, 2009, 8:24:48 AM5/1/09
to pon...@googlegroups.com
呵呵 了解一下编译的基本知识 和一些常用的优化方式也不是什么坏事



--
最初的梦想

Eric.Wang

unread,
May 1, 2009, 9:11:36 AM5/1/09
to TopLanguage
我们的结论一致,那就是朴实无华的代码通常比落英缤纷的代码更好。但是我们做出这个结论的理由不一样。

我的理由是朴实无华的代码通常更容易维护,因为朴实的代码更容易阅读,更不容易产生误解。这代表着程序不容易出错,代码容易移交,问题容易定位和修改。
最终这会代表着高质量可延续的成功项目。

你的理由是团队里面有人水平参差不齐,所以不能写复杂的代码。言下之意,如果团队里面都是C++精英,那么你就会倾向于写复杂的代码了。
你的另一个理由是coder不能接受复杂的代码风格。言下之意,如果想办法让他们接受了这种风格,那么你会推动使用复杂风格的代码。

我的观点是朴实的代码本身就比复杂的代码更好。写朴实无华的代码是一个主动的选择,而不是由于团队原因作出的被动选择。假如有两个团队,水平都很高,一
个团队写朴实的代码,一个团队写复杂的代码,那么写朴实代码的那个团队更有可能把项目做好。


On 5月1日, 下午7时38分, Fei Yan <skyscribe...@gmail.com> wrote:
> 2009/5/1 Eric.Wang <wangshaoq...@gmail.com>

James Z.M. GAO

unread,
May 1, 2009, 10:11:14 AM5/1/09
to TopLanguage
"for" 曾经也是很华丽的语法; 如果未来c++有了其他循环谓词, for_each
可能也成了"朴实", 呵呵. 如果不考虑细微的性能差别, 对于同一个目的,
选择不同的语法特性时, 更多会考虑共同的"认同感", 共同的知识基础等.
所以我认为不应该在"华丽"这个问题上谴责for_each, 推崇for,
他们都可能编译出高效的汇编代码, 也都能写出易于维护的高级代码.
所谓的"朴实无华", 我想其实是在说: "我们这一代程序员是学c长大的,
我们都习惯于读for写的代码, for_each的语意我们不熟悉".

for (c语法) 和 for_each (stl语法) 是不同抽象模型下的产物,
能解决不同问题的主要矛盾. 只要不是炫耀语法就行. 至于两种语法都适用的情况,
成熟的team应该根据大家的接受程度选择一种, 个人的项目, 可以完全跟着感觉走,
呵呵.

说的没什么论点, 想到哪里说到哪里, 呵呵

空气

unread,
May 2, 2009, 6:10:15 AM5/2/09
to TopLanguage
char a[] = "abcdef";
int size;
int i, j;

size = strlen(a);
for (j = 0; j < 10000000; j++)
for (i = 0; i < size; i++)
;

processed in 0.140625 seconds


char a[] = "abcdef";
int size;
int i, j;

for (j = 0; j < 10000000; j++)
for (i = 0; i < strlen(a); i++)
;
processed in 0.671875 seconds

测试环境,VS2005


或许应该说,”编译器有可能优化“?

但我确实是没见过有优化的。


On 4月29日, 下午8时04分, LeeoNix <leeoni...@gmail.com> wrote:
> 你错了,是会优化成这样的,不信你可以看反汇编。
>
> 这个是一个事实。
>
> 编译器会判断循环体的。
>

> 2009/4/29 空气 <lct8...@gmail.com>

空气

unread,
May 2, 2009, 6:18:14 AM5/2/09
to TopLanguage
记得刚刚学编程的时候,有一个题目是求某数N是否是质数。

其中要计算N的开方,放在循环条件中,老师就强调说不要写成
i < power(N, 0.5)
而应该写成
p = power(N, 0.5);
i < p

Fei Yan

unread,
May 2, 2009, 7:41:19 AM5/2/09
to pon...@googlegroups.com
测试了下你的这个小程序,并将循环次数设置为原来的十倍(100000000),结果如下:
-----------------------------------------
 g++  test.cpp
 ./a.out
Time spent on func1 is 1249109 microseconds
Time spent on func2 is 8944406 microseconds

g++ -O1 test.cpp
 ./a.out
Time spent on func1 is 573395 microseconds
Time spent on func2 is 558024 microseconds

 g++ -O2 test.cpp
 ./a.out
Time spent on func1 is 1 microseconds
Time spent on func2 is 0 microseconds

 g++ -O3 test.cpp
 ./a.out
Time spent on func1 is 0 microseconds
Time spent on func2 is 0 microseconds

可以看出,O2之后已经觉察不到差别了。

机器环境: Debian 5.0  x86_64, Pentium D 2.8G Dual Core, Memory 2.5G.

程序如下:
#include <cstring>
#include <cstdio>
#include <iostream>
#include <sys/time.h>

using namespace std;

struct counter{
    struct timeval tm_;
    const char* hint_;
    counter(const char* hint):hint_(hint)
    { 
        gettimeofday(&tm_, 0);
    }
    ~counter()
    {
        struct timeval tm1;
        gettimeofday(&tm1, 0);
        size_t diff = (tm1.tv_sec - tm_.tv_sec) * 1000000 +
            tm1.tv_usec - tm_.tv_usec;
        cout << "Time spent on " << hint_ << " is " << diff << " microseconds" << endl;;
    }
};

void func1()
{

    char a[] = "abcdef";
    int size;
    int i, j;

    counter tmp("func1");
    size = strlen(a);
    for (j = 0; j < 100000000; j++)  
        for (i = 0; i < size; i++);
}

void func2()
{

    char a[] = "abcdef";
    int size;
    int i, j;
   
    counter tmp("func2");
    for (j = 0; j < 100000000; j++)  
        for (i = 0; i < strlen(a); i++);
}

int main()
{
    func1();
    func2();
    return 0;
}











2009/5/2 空气 <lct...@gmail.com>

Fei Yan

unread,
May 2, 2009, 7:45:22 AM5/2/09
to pon...@googlegroups.com
补充一下,编译器版本:
g++ -v

Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1.1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-cld --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1)


2009/5/2 Fei Yan <skyscr...@gmail.com>

LeeoNix

unread,
May 2, 2009, 9:19:10 AM5/2/09
to pon...@googlegroups.com
说明你还不是很了解现代的编译器。
 
你测试用VS2005,但是你还是不了解cl.exe的命令行和真正优化的地方。
 
另外,VS的Debug版本和Release版本是两样的,一定记住这一点。
 
我上米说得end(),在Debug版本是不会被优化的,而在Release版本的时候就会被彻底优化。
 
具体见Linker选项生成的命令行的区别。

2009/5/2 空气 <lct...@gmail.com>

殷远超

unread,
May 2, 2009, 10:46:18 AM5/2/09
to pon...@googlegroups.com
同意,事实上很多时候,前期的不必要优化成了后期的梦魇。我愿意去理解这两种之间的差别,在确认编译器不能优化,并且自己很在乎这一块效率的时候,才去优化。
无profile,不优化~

2009/4/30 Eric.Wang <wangsh...@gmail.com>

我倾向于
vector<int> ivec;
for(vector<int>::iterator it = ivec.begin(); it != ivec.end(); it++)

因为简洁明快,所见即所得。

优化 is another case。

一个程序里面,其实大部分代码都是不用优化的。为了这些不用优化的地方付出额外代价,其实就是损失。

在需要优化的地方做优化。不需要优化的地方,就写得简洁明快一点,好维护。



--
殷远超 http://www.yinux.com

殷远超

unread,
May 2, 2009, 11:26:33 AM5/2/09
to pon...@googlegroups.com
人家是说for的比较条件上面的优化,你用了个二级循环把那个放到循环体里面了。

2009/5/2 空气 <lct...@gmail.com>

for (j = 0; j < 10000000; j++)
       for (i = 0; i < strlen(a); i++)

               ;
 processed in 0.671875 seconds


--
殷远超 http://www.yinux.com

skyscribe

unread,
May 2, 2009, 11:46:04 PM5/2/09
to TopLanguage
从求知的角度来讲,值得去搞清楚这些细节,本身没有多大坏处。

从实用的角度,写代码还是简洁明了的好。这种差异,在Review的时候,就是non-issue,没有对错。
我个人接触到的代码,从没有到需要优化这一块的地步。
纠结于此类细节上边,code review的时候岂不累死人?

On 5月2日, 下午10时46分, 殷远超 <yinyuanc...@gmail.com> wrote:
> 同意,事实上很多时候,前期的不必要优化成了后期的梦魇。我愿意去理解这两种之间的差别,在确认编译器不能优化,并且自己很在乎这一块效率的时候,才去优化。
> 无profile,不优化~
>

> 2009/4/30 Eric.Wang <wangshaoq...@gmail.com>

LeeoNix

unread,
May 3, 2009, 12:44:08 AM5/3/09
to pon...@googlegroups.com
累死人?
 
我不知道你code review是怎么用的。
 
要知道程序员一个永远都通用的规则:宁愿花时间做工具去做也不要花一秒钟手工去干。
 
grep是个很好的工具,类似的工具也很多。
 
脚本也是个很好的工具,尤其Python和Perl在处理文本的时候。
 
正则表达式是很强大的,lint是很有用的。
 
版本控制的差异,各种类型的比较工具都是有异议的,
 
真的会如你所说的“累死人”。
 
一个团队里保持一种风格就可以了,如果不被大家所认同,那花时间修改是绝对有必要的。

2009/5/3 skyscribe <skyscr...@gmail.com>

Fei Yan

unread,
May 3, 2009, 2:12:27 AM5/3/09
to pon...@googlegroups.com
火气这么大可不是什么好事情...
我只是陈述一种事实而已,现实中不带这么理想化的;coding standards我说遇见的也从来没有细化到这一步的...

扯上正则表达式、python/perl, 是一种质问别人弱智的口气...
不参与这种无意义的争论

2009/5/3 LeeoNix <leeo...@gmail.com>

LeeoNix

unread,
May 3, 2009, 2:21:24 AM5/3/09
to pon...@googlegroups.com
我没质问你。或许你认为我口气大了。可是我说的对事不对人,请不要和你本人扯上关系。
 
如果代码很多,手工方式是大忌。所谓“累死人”的事情我只在编码的时候发现过。
 
我只是说一个习惯,并没有涉及到review这一块。
 
你说到review的时候,这个习惯是分团队的,不关什么习惯和风格,都是团队优先的。
 
并没有绝对化的公式。如果你认为你的编译器可以做到优化,怎么写是组织者考虑的方式。
 
当然for_each是好选择。

2009/5/3 Fei Yan <skyscr...@gmail.com>

Fei Yan

unread,
May 3, 2009, 2:29:48 AM5/3/09
to pon...@googlegroups.com
有时间建议你找个其他人,仔细读一下你回复的内容,看看别人的第一反应是什么。

我只是善意的提醒你一下,你的回复让人感觉强烈的不舒服,很难让人感觉你是对事不对人的。

如果你确实是对事不对人,建议你(也包括我)仔细琢磨琢磨潜在的原因肯定是很有好处的,很多时候技术本身不是看起来那么的重要(当然也不是说不重要)。


2009/5/3 LeeoNix <leeo...@gmail.com>

chaoyan ma

unread,
May 3, 2009, 3:19:42 AM5/3/09
to pon...@googlegroups.com
(⊙o⊙)… 
其实 我比较关心 比如下面这个例子 里面的 j*j 能不能优化……
 
char a[] = "abcdef";
int size;
int i, j;
for (j = 0; j < 10000000; j++)
       for (i = 0; i < 10000000*strlen(a); i++)
              {
                        i*j*y*j*x;
                      } ;

--
最初的梦想

Roof

unread,
May 3, 2009, 3:29:17 AM5/3/09
to TopLanguage
看到你们争的挺激烈,来凑凑热闹。
首先,这个帖子题目就大有问题,简直属于坑贴。
"有些代码习惯,是交给编译器,还是自己就写的好一些。"
注意"有些"这两个字,基本上我们正反都是对的。肯定是有些交给编译器,有些交给自己了。
对于代码习惯,从程序员角度看,如果学习了一个认为更好的,肯定是去培养更好的习惯,
正如for循环迭代部分++i优于i++一样,如果去抨击别人使用i++,未免显得不够厚道。但从
自身编程修养的角度出发,养成++i这个习惯,绝对不会是坏事。
我曾经看到一个人使用:
for ( int i = 0; i < strlen(str); i++ )
这种写法,我询问它为什么不把程度存在临时变量,他的回答是现在的编译器会对此作出优
化的。
我同意他的说法。但我不同意纵容自己写出依赖编译器优化的编码习惯来,要知道养成好的
习惯不容易,你必须每次都坚持做至少目前看来是正确的事。而如果抱着需要的时候才做正
确的事,恐怕这和"从明天起我一定要早起"是差不多的美好愿望。
另外LeeoNix说的"程序员一个永远都通用的规则:宁愿花时间做工具去做也不要花一秒钟手
工去干。"我深表赞同,握个手先,只是目前居然淹没在各种繁忙琐事中,没有在这方面下
功夫,sigh,自我bs下。

On 5月3日, 下午2时29分, Fei Yan <skyscribe...@gmail.com> wrote:
> 有时间建议你找个其他人,仔细读一下你回复的内容,看看别人的第一反应是什么。
>
> 我只是善意的提醒你一下,你的回复让人感觉强烈的不舒服,很难让人感觉你是对事不对人的。
>
> 如果你确实是对事不对人,建议你(也包括我)仔细琢磨琢磨潜在的原因肯定是很有好处的,很多时候技术本身不是看起来那么的重要(当然也不是说不重要)。
>

> 2009/5/3 LeeoNix <leeoni...@gmail.com>


>
> > 我没质问你。或许你认为我口气大了。可是我说的对事不对人,请不要和你本人扯上关系。
>
> > 如果代码很多,手工方式是大忌。所谓"累死人"的事情我只在编码的时候发现过。
>
> > 我只是说一个习惯,并没有涉及到review这一块。
>
> > 你说到review的时候,这个习惯是分团队的,不关什么习惯和风格,都是团队优先的。
>
> > 并没有绝对化的公式。如果你认为你的编译器可以做到优化,怎么写是组织者考虑的方式。
>
> > 当然for_each是好选择。
>

> > 2009/5/3 Fei Yan <skyscribe...@gmail.com>


>
> > 火气这么大可不是什么好事情...
> >> 我只是陈述一种事实而已,现实中不带这么理想化的;coding standards我说遇见的也从来没有细化到这一步的...
>
> >> 扯上正则表达式、python/perl, 是一种质问别人弱智的口气...
> >> 不参与这种无意义的争论
>

> >> 2009/5/3 LeeoNix <leeoni...@gmail.com>


>
> >> 累死人?
>
> >>> 我不知道你code review是怎么用的。
>
> >>> 要知道程序员一个永远都通用的规则:宁愿花时间做工具去做也不要花一秒钟手工去干。
>
> >>> grep是个很好的工具,类似的工具也很多。
>
> >>> 脚本也是个很好的工具,尤其Python和Perl在处理文本的时候。
>
> >>> 正则表达式是很强大的,lint是很有用的。
>
> >>> 版本控制的差异,各种类型的比较工具都是有异议的,
>
> >>> 真的会如你所说的"累死人"。
>
> >>> 一个团队里保持一种风格就可以了,如果不被大家所认同,那花时间修改是绝对有必要的。
>

> >>> 2009/5/3 skyscribe <skyscribe...@gmail.com>

LeeoNix

unread,
May 3, 2009, 4:52:41 AM5/3/09
to pon...@googlegroups.com
我并没有发现我说的话里有什么问题。

要知道,当一个观点被语气强烈的反驳的时候,

你的自尊心会稍微的受点伤害,就好像你本人受到伤害一样。

或许我质问的是你“累死人”这三个字的原因。

我回答的时候会奇怪你为什么说这三个字。

当真的会出现很辛苦的code review的时候,那就去借助工具,这本身就是一个最初就应该做的选择。

强烈的不舒服,是你的内心的某一块涉及到尊严的小地方受到触碰了。

如果你把它当回事,就当回事了。

你不把它当回事,也就没事了。

可能与你刚才的心情有关,也可能与你外界的因素有关。


2009/5/3 Fei Yan <skyscr...@gmail.com>

Eric.Wang

unread,
May 3, 2009, 5:07:20 AM5/3/09
to TopLanguage
没有测试,就不做优化。
要写出一个性能好的程序,首先是框架合理,然后是代码基本写完之后通过测试找出瓶颈,针对瓶颈做优化。
一边写代码一边优化,很容易写出拗口的代码来。
拿你举的这个例子来说,我觉得for ( int i = 0; i < strlen(str); i++ )没什么不好。不是因为编译器会优化,而
是因为这样写简洁好看。如果这行代码会影响程序的效率,那么在性能测试的时候自然会找到这里并优化这里的;如果这行代码根本就不会影响程序的整体性能,
那么就没有必要关心这行代码的性能。

James Z.M. GAO

unread,
May 3, 2009, 6:16:23 AM5/3/09
to TopLanguage
"简洁好看" 的标准是什么, 是代码短还是使用的变量少? 还是纯粹主观印象,
只要易于理解就行?

我想应该是指主观吧. 但是主观太容易变化了,
而且我们可以根据需要改变习惯和长期的主观感受,
我们可以逐渐让自己觉得"另一种"写法更"好看" (其实都很简洁).
我们尊重主观的多样性, 但更欣赏好的习惯.

Eric.Wang

unread,
May 3, 2009, 7:19:26 AM5/3/09
to TopLanguage
代码风格的主要目标是易于理解。这个易于理解是指C++程序员阅读起来轻松,没负担,所见即所得。
简洁好看、所见即所得的代码通常是比较容易理解的。

代码风格和性能无关,这是我的主要观点。如果确实需要性能,再丑陋的代码都是可以接受的。如果没有特别的性能要求,代码总是写得越容易理解越好。

for ( int i = 0; i < strlen(str); i++ )我就觉得是所见即所得的代码。多定义一个int就多绕一个弯。这行代
码不要求性能的话,就没必要再额外引入一个int变量。

高性能的程序,首先是框架合理。然后是测试之后针对瓶颈做优化。

把写代码和性能优化混在一起,很容易导致代码变得拗口。

再拿上面那个i++和++i的例子来说,我是鼓励写i++的。你如果要写成++i,你需要给出理由:因为这里极端需要性能。
为什么?因为i++比较顺口,“i加加”,有主语有谓语,是主语“i”做加加的动作;而“++i”读作“加加i”,动作的主体"i"跑到宾语的位置去
了。

Roof

unread,
May 3, 2009, 7:33:07 AM5/3/09
to TopLanguage
你的意思我能理解。先编写简洁、可读性强的代码,在发现性能瓶颈时再去做局部优化,确实是很多前人宝贵
经验的总结。不过就这个例子而言,我认为你未免主观了点。特别是“多定义一个int就多绕一个弯”,这个观点
我是不能理解的:) 至于i++和++i哪个顺口,看起来也是个特别主观的话题。
所谓主谓语的观点是站不住脚的(没有冒犯的意思)。如果要研究纯粹的语言含义,那么按你的说法,
i++的意思是i自增加,嗯,没错
++i呢,就是把i增加1
两个说法如同“他自杀”和“打死他”一样,其实最后公说公有理,婆说婆有理,我认为对两个写法最好采取宽容态
度,除非小组已经定义了一定要用哪个。

chaoyan ma

unread,
May 3, 2009, 7:35:44 AM5/3/09
to pon...@googlegroups.com
~~  楼上的 多定一个变量就很丑陋吗?++i 比i++丑陋吗?
那些代码是对性能没要求的呢?
 



--
最初的梦想

chaoyan ma

unread,
May 3, 2009, 7:37:49 AM5/3/09
to pon...@googlegroups.com
不好意思 有点冲突了 是楼上的楼上
--
最初的梦想

missdeer

unread,
May 3, 2009, 7:40:21 AM5/3/09
to TopLanguage
如果单纯从代码风格考虑的话,我一般倾向于用for_each甚于for,在我看来大多数时候,循环体是一段独立的逻辑,提取成一个functor或一
个method很合理而且有必要,如果代码实在短得可以,就用boost::lambda凑合一下。

Eric.Wang

unread,
May 3, 2009, 7:52:32 AM5/3/09
to TopLanguage
我同意你说的采取宽容态度。实际上我们公司的编码规范文档里面,也只是“建议”写成i++,没做强制要求,呵呵。

除开性能不说,我还是认为i++更顺口。可能是我接触的人还不够多,之前我遇到的人没有人认为++i更顺口的,他们使用++i的理由清一色是为了更好的
性能。
拿上面那位老兄为例子来说,他很自然的就写了for ( int i = 0; i < strlen(str); i++ ),里面用的是i++。这
很自然,很好(如果不要求性能的话)。

skyscribe

unread,
May 3, 2009, 7:56:52 AM5/3/09
to TopLanguage
呵呵,又被骂了一次气量小?

很讨厌这种咬着别人不放的偏激行为,但愿自己没有做出这种行为,想找理由怎么都找到的,关键是口头的争论有什么用处呢,不知道你有没有在公司里边做过正
儿八经的项目,真实的工作中,你遇到过这样的情况?

尊重别人也是一种美德呀

况且你本身已经大大曲解了我的真实意思,把话题转移到其他上面来印证你的是对的,并为对方假想了一个离题很远的观点作为批驳对象(我可没有说过
code review没有好的工具之类的,这些都是你的臆测,真实的情况是,我们的code review已经进行了几年,没有人抱怨说很苦之
类。。。)

你后边两次的回复里边提到的方面观点和我要表达的已经差异很大了

不多说什么了,不参与这个帖子的讨论了

楼主很喜欢挖坑,一不小心就中招;看来以后得绕着走啊

On 5月3日, 下午4时52分, LeeoNix <leeoni...@gmail.com> wrote:
> 我并没有发现我说的话里有什么问题。
>
> 要知道,当一个观点被语气强烈的反驳的时候,
>
> 你的自尊心会稍微的受点伤害,就好像你本人受到伤害一样。
>
> 或许我质问的是你"累死人"这三个字的原因。
>
> 我回答的时候会奇怪你为什么说这三个字。
>
> 当真的会出现很辛苦的code review的时候,那就去借助工具,这本身就是一个最初就应该做的选择。
>
> 强烈的不舒服,是你的内心的某一块涉及到尊严的小地方受到触碰了。
>
> 如果你把它当回事,就当回事了。
>
> 你不把它当回事,也就没事了。
>
> 可能与你刚才的心情有关,也可能与你外界的因素有关。
>

> 2009/5/3 Fei Yan <skyscribe...@gmail.com>


>
> > 有时间建议你找个其他人,仔细读一下你回复的内容,看看别人的第一反应是什么。
>
> > 我只是善意的提醒你一下,你的回复让人感觉强烈的不舒服,很难让人感觉你是对事不对人的。
>
> > 如果你确实是对事不对人,建议你(也包括我)仔细琢磨琢磨潜在的原因肯定是很有好处的,很多时候技术本身不是看起来那么的重要(当然也不是说不重要)。
>

> > 2009/5/3 LeeoNix <leeoni...@gmail.com>


>
> >> 我没质问你。或许你认为我口气大了。可是我说的对事不对人,请不要和你本人扯上关系。
>
> >> 如果代码很多,手工方式是大忌。所谓"累死人"的事情我只在编码的时候发现过。
>
> >> 我只是说一个习惯,并没有涉及到review这一块。
>
> >> 你说到review的时候,这个习惯是分团队的,不关什么习惯和风格,都是团队优先的。
>
> >> 并没有绝对化的公式。如果你认为你的编译器可以做到优化,怎么写是组织者考虑的方式。
>
> >> 当然for_each是好选择。
>

> >> 2009/5/3 Fei Yan <skyscribe...@gmail.com>


>
> >> 火气这么大可不是什么好事情...
> >>> 我只是陈述一种事实而已,现实中不带这么理想化的;coding standards我说遇见的也从来没有细化到这一步的...
>
> >>> 扯上正则表达式、python/perl, 是一种质问别人弱智的口气...
> >>> 不参与这种无意义的争论
>

> >>> 2009/5/3 LeeoNix <leeoni...@gmail.com>


>
> >>> 累死人?
>
> >>>> 我不知道你code review是怎么用的。
>
> >>>> 要知道程序员一个永远都通用的规则:宁愿花时间做工具去做也不要花一秒钟手工去干。
>
> >>>> grep是个很好的工具,类似的工具也很多。
>
> >>>> 脚本也是个很好的工具,尤其Python和Perl在处理文本的时候。
>
> >>>> 正则表达式是很强大的,lint是很有用的。
>
> >>>> 版本控制的差异,各种类型的比较工具都是有异议的,
>
> >>>> 真的会如你所说的"累死人"。
>
> >>>> 一个团队里保持一种风格就可以了,如果不被大家所认同,那花时间修改是绝对有必要的。
>

> >>>> 2009/5/3 skyscribe <skyscribe...@gmail.com>

Eric.Wang

unread,
May 3, 2009, 8:03:47 AM5/3/09
to TopLanguage
你可以参考一下lighttpd的代码,lighttpd是一个优秀的高性能的web server。

http://www.lighttpd.net/download/lighttpd-1.4.22.tar.gz

里面的代码我摘录几段:
array.c:
for (j = a->used; j < a->size; j++) a->data[j] = NULL;

mod_scgi.c:
for (i = 0; i < f->used; i++) {

server.c:
for (i = 0; i < FILE_CACHE_MAX; i++) {

request.c
for (; *c && *c != ']'; c++) {


你看,清一色都是写成i++的形式。

chaoyan ma

unread,
May 3, 2009, 8:04:38 AM5/3/09
to pon...@googlegroups.com
……
其实还想很小声的问一句,优化后 i++;和++i;   不一样的吗?


--
最初的梦想

Fei Yan

unread,
May 3, 2009, 8:16:32 AM5/3/09
to pon...@googlegroups.com
貌似对于builtin类型而言,++i和i++并没有什么差异的...

具体细节不太记得了,有兴趣的查一下汇编

James Z.M. GAO

unread,
May 3, 2009, 10:06:44 AM5/3/09
to pon...@googlegroups.com
对于没重载的操作符, 并且返回值没有被用到, 优化出来的汇编一样的,
如果优化之后还是有差别, 那个编译器可能是30年前写的, 呵呵;
如果返回值用到了,
大部分情况仅仅是寄存器和内存操作的顺序不一样(视上下文而定,
有些会连续几个运算符一起优化), 性能差距很小. 倒是把i++和++i换成--i,
循环倒置, 产生的效果更大一些. 一般循环体很依赖循环顺序, 编译器很难优化,
倒置后会节省很多带宽和指令. 只是倒置后, 就更不"易读" 了, 呵呵.

ps: 如果考虑l-value的话, ++i更流畅易懂些

LeeoNix

unread,
May 3, 2009, 9:53:40 AM5/3/09
to pon...@googlegroups.com
定一个int绕一个弯?如果你用纯C的代码

for( int i =0; ;)
这样都不给你用的。

只能int i;
for( i = 0; ; )

由不得你不定义,当定义一个i的时候,可以一起定义一个size。

int i, size = strlen(s);
for (i =0; i< size; ++i)

这样的,适合在纯C代码运行的,是否符合你的审美观呢?

而且你陷入了一个误区,代码的好坏,不是++i和i++所能区分的,
这个不是主要的方向,习惯只要团队里面大家接受就可以了,
当问题纠结在++在前在后的问题的时候,主要的业务就被迷失了。

下面是跑题加玩笑:
你的语言习惯和所谓的代码语言习惯,是不靠谱的。呵呵,你的这个:
“为什么?因为i++比较顺口,“i加加”,有主语有谓语,是主语“i”做加加的动作;而“++i”读作“加加i”,动作的主体"i"跑到宾语的位置去了。”
貌似是中国习惯,如果是日语,是主宾谓的习惯呢?
你的主语谓语的说法,
所谓的“加加i”,其实是i自增,在英语里是increase,也就是说increase i,这么一条语句。
如果抛开操作符,用函数表达,就是increase(i)。
所以,i本身就是宾语的位置。
而i++的意思是increase(i) and return self 其实是两个意思。

以上跑题加玩笑。见谅。

回到题目上来:

我曾经看到一个优秀的代码,他的循环体是 i+=1
类似如下:
for (int i = 0; i < size; i += 1)

但这样写也不妨碍是一份优秀的代码。

所以呢,Eric.Wang不能拿某一份优秀的代码为“标准”去“匹配”某些不是这么写“i++”的代码。这个事偏颇的。

2009/5/3 Eric.Wang <wangsh...@gmail.com>

LeeoNix

unread,
May 3, 2009, 9:58:00 AM5/3/09
to pon...@googlegroups.com
嗯,没错,倒置性能会提高。

记得以前分析delphi的编译器,如果循环体没有很复杂的逻辑,编译器会把Pascal的for循环从后往前循环。

2009/5/3 James Z.M. GAO <gao...@gmail.com>

OxFAN

unread,
May 3, 2009, 9:19:07 AM5/3/09
to pon...@googlegroups.com
不知道优化后什么样,一般情况下++i性能要好一些,主要是指当i是对象的时候,后缀++会产生一个临时对象(额外的复制过程),而前缀++不会(估计大家都知道...)。至于++i和i++哪个读起来顺口,这因人而异,这问题讨论起来没啥味道。

我想一般人都比较习惯i++,但是又不能忽视性能问题,我现在在慢慢习惯前缀形式。

补充一些关于“优化”的看法:个人认为不应该明显的依赖编译器优化。
      首先,编译器的优化是隐藏的,一般情况下了解不到编译器的优化细节,也没必要去了解。
      其次,编译器的进行优化的前提是代码符合优化的条件,就是说如果需要优化也要尽可能的满足编译器优化的条件(比如正确的尾递归等),这些工作是程序员做的。
      再次,需要明确的一点是,编译器都有优化功能,而且通常会分等级,低级的优化是必要的,中高级的优化是辅助性的,一般是针对特定的情况做优化,其目的就是为了减少程序员工作量,使代码简洁,提高程序性能。

James Z.M. GAO

unread,
May 3, 2009, 10:16:24 AM5/3/09
to pon...@googlegroups.com
c89的确是. (c99可以"for(int i"的).
补充一个例子, 下面那个更直观易读呢:

=============================
{
int f = foo(aaaaaaaaaaa,
bbbbbbbbbbbbbbbbb,
cccccccccccccccc,
ddddddddddddddddd,
eeeeeeeeeeeeeeeeee);

for(int i = 0; i < f; i++);
}

===============================

for(int i = 0; i <
foo(aaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbb,ccccccccccccc,ddddddddddd,eeeeeeeeeee);
i++);

===============================

我想多一个变量(第一种写法)更易读了吧~

LeeoNix

unread,
May 3, 2009, 10:03:37 AM5/3/09
to pon...@googlegroups.com
BTW:如果Ken Thompson老头没有发明++和--,之前他是怎么处理这个的……

写个函数叫

void inc(int* i)

inc(&i) //这样?

int inc(int i)
i = inc(i);  //还是这样?

2009/5/3 LeeoNix <leeo...@gmail.com>

LeeoNix

unread,
May 3, 2009, 10:06:21 AM5/3/09
to pon...@googlegroups.com
可是我的编译器不支持这个,约定好用C方式编译,出错。循环体外声明,就搞定。

gcc现在新的版本是不是支持c99标准了?

2009/5/3 James Z.M. GAO <gao...@gmail.com>
c89的确是. (c99可以"for(int i"的).

qiaojie

unread,
May 3, 2009, 10:06:32 AM5/3/09
to pon...@googlegroups.com
无法理解在C++用for_each代替for能得到什么好处。难道定义functor很方便吗?在我看来那就是把一段本是高内聚的代码拆分的七零八落。如果for_each内需要访问外面的变量又怎么办呢?难道都传到functor对象里去?多么别扭啊
missdeer 能不能举几个例子,让我看看for_each代替for的好处?
  
 

 
2009/5/3 missdeer <miss...@gmail.com>

James Z.M. GAO

unread,
May 3, 2009, 10:23:01 AM5/3/09
to pon...@googlegroups.com
写Pascal compiler的是个神, 呵呵, 那也只能处理简单的情况呀~
大部分情况循环体严重依赖计算顺序, 等价的变换很难找甚至没有,
所以只能靠人了~

ps: 仅仅脚标倒置, 在循环内部坐标变换, 不会提高性能,
因为循环内部还需要至少多一次的读取和计算~

James Z.M. GAO

unread,
May 3, 2009, 10:24:09 AM5/3/09
to pon...@googlegroups.com
gcc -std=c99

James Z.M. GAO

unread,
May 3, 2009, 10:26:44 AM5/3/09
to James Z.M. GAO, pon...@googlegroups.com
c99 很多入侵式的特性, 使得gcc默认不去支持. 开了std之后, 有些gcc
extention特性就没有了, 比如inline asm, 鱼和熊掌不能兼得呀~

Eric.Wang

unread,
May 3, 2009, 10:26:33 AM5/3/09
to TopLanguage
这不仅仅是"某一份优秀的代码",我看的不仅仅是lighttpd,只是恰好拿它出来做例子而已。

我们来赌一下吧:你们谁找任意一个优秀的开源项目,如果这个项目是以++i为主,我就单独发帖承认i++并不能代表优秀的品位。

这个赌注很不公平,因为你们只要找到一个反例就可以了,而我的立场是“所有”优秀开源项目代码都是尽量使用i++的。
(对优秀下个定义吧,代码在10w行以上,下载超过100w以上)

我看过的代码很有限,因此这对我并不是一个很有把握的赌注。我有不小的概率会输掉这个赌注。不过,如果我输了这个赌注,但是能够增长我的见识,那还是划
算的。

> 2009/5/3 Eric.Wang <wangshaoq...@gmail.com>

LeeoNix

unread,
May 3, 2009, 10:27:46 AM5/3/09
to pon...@googlegroups.com
呵呵,Eric.Wang兄说起自己喜欢看某些风格的代码,想起了梁兄的《编程高手箴言》里面大肆批驳的代码。
其实习惯团体习惯就足够了。
说起习惯,我在说一下其他两个习惯,
与0比较和函数参数是void。

我知道中国很多因为用VC的原因,用NULL宏的特别多,

假设变量p是指针,

下面作何选择呢?
if (p) if (p != NULL) if (p != 0)
if (!p) if (p == NULL) if (p == 0)

大家到底到底喜欢那个呢?

我个人就喜欢if (p) 和 if (!p),因为打字少……而且不会出所谓的少写一个=的问题。
仅仅是个人喜欢,不代表大众意愿,相比大家对于这个的习惯区别都很大吧。
而在采访Stroustrup的时候,他倾向于和0比较,而不是用NULL宏。这是他的习惯,可以奉行为圣言,也可以无视他。

看到这个,想起林锐以前写的那本《高质量C++代码指南》最初的版本里面,希望程序员区别这三个比较方式,明确为布尔变量、指针、数字类型。
呵呵,他的想法倒是很理想化。

另外就是 void foo(void) 和 void foo()
我看到过很多人写void foo(void),Stroustrup在他的书里面明确表示了他的反感,称为“可憎的void”。

不知道大家有没有习惯void foo(void)这样写法的习惯。

LeeoNix

unread,
May 3, 2009, 10:30:01 AM5/3/09
to pon...@googlegroups.com
很不幸,我从不参与任何博彩类的活动。包括所谓的口头打赌,这个不符合我的价值观。

打赌有意义吗?包括现实中争论的时候,面红耳赤的时候站起来就说:我敢和你打赌。类似这个如何如何。

打赌是争论到了极端之后用的极端方法而已。

你不能用代码数量去说明i++就是比++i如你意愿中的所谓的“优秀”。

更不能用打赌的方式去解决这个问题。你很喜欢这个方式吗?

2009/5/3 Eric.Wang <wangsh...@gmail.com>

avalon xu

unread,
May 3, 2009, 10:34:38 AM5/3/09
to pon...@googlegroups.com
这个group正在沦落为水潭了。
记得以前讨论过国内外程序员的差异,国内外的mailing list就是个缩影,国外的好点的技术mailing list哪有这么多无聊的水贴。
真有时间或真有代码优化心得,就谈谈优化技术,比如我们以前做优化,为了消除分支让代码顺序执行,在运行时根据状态动态生成代码然后跳转执行...我不觉得i++和++i会对程序性能有什么改变。
当初这个group吸引我的地方是里面经常讨论一些小的算法问题,我很喜欢在平时不忙的时候思考一些数学小问题来消磨时间. 不过现在这点乐趣也找不到了,我觉得pongda应该对topic的质量做些管理了,这种水贴直接删除的好, 没啥好讨论的。


LeeoNix

unread,
May 3, 2009, 10:37:41 AM5/3/09
to pon...@googlegroups.com
补充一下,某个阶段,某些男子汉把参与“打赌”当做“男人的表现”,证明他们很有勇气,

当我退出的时候,某些人对我说:你不是男人,没勇气。我只是笑笑。

博彩,在我眼里,小赌也是赌,大赌也是赌,口头的打赌也是赌,

而随之而产生的赌博心理我不想有,这个算不得勇气,

请Eric.Wang稍微理智一点参与话题好吗?

我们是讨论,不是争论,也不是争论到最后站起来拍桌子之后面红耳赤的对我说:我敢和你打赌。用i++的绝对比++i的多。

就算你赢了又如何?你获得了什么?我赢了又如何?我又获得了什么?

答案很明显,什么都没获得,获得的只是你内心的某些报复性的“快感”而已。

我赢了,你输了,类似这样。

仍旧没有获得有价值的东西。

2009/5/3 LeeoNix <leeo...@gmail.com>

Eric.Wang

unread,
May 3, 2009, 10:43:51 AM5/3/09
to TopLanguage
目前我看过的优秀开源项目代码,都是使用i++风格的。我认为,如果优秀的项目都这样写,必然代表着好的品位。这是逻辑上的归纳法。
我对我的代码要求不高,代码风格能够达到那些优秀开源项目代码的程度就足够了。

打赌只是好玩而已。因为逻辑无法证明观点的时候,事实能够作为最好的标杆。

PS: 我从不买彩票,因为我相信概率学。但是打个无伤大雅的赌注,未尝不可。上面那个赌注不是概率问题。

再PS:国内有篇林锐写的关于代码风格方面的文章,里面有不少谬误,大概误导了很多人。如果林锐同学也看到了这个帖子,请多多包涵,我是对事不对人。

再再PS:"NULL =="和"== NULL"也是类似的情况。左值理论可以为前者撑腰,但是几乎所有优秀开源代码都是写成后者的。(除了
eMule的代码,eMule的代码大概有一半是写成前者的)。这个问题,我倒是对十几个最成功的开源项目代码做了统计。


On 5月3日, 下午10时30分, LeeoNix <leeoni...@gmail.com> wrote:
> 很不幸,我从不参与任何博彩类的活动。包括所谓的口头打赌,这个不符合我的价值观。
>
> 打赌有意义吗?包括现实中争论的时候,面红耳赤的时候站起来就说:我敢和你打赌。类似这个如何如何。
>
> 打赌是争论到了极端之后用的极端方法而已。
>
> 你不能用代码数量去说明i++就是比++i如你意愿中的所谓的“优秀”。
>
> 更不能用打赌的方式去解决这个问题。你很喜欢这个方式吗?
>

> 2009/5/3 Eric.Wang <wangshaoq...@gmail.com>

Eric.Wang

unread,
May 3, 2009, 10:44:58 AM5/3/09
to TopLanguage
你可以不理会我的赌注。

我期待有人来让我输掉那个赌注。


On 5月3日, 下午10时37分, LeeoNix <leeoni...@gmail.com> wrote:
> 补充一下,某个阶段,某些男子汉把参与“打赌”当做“男人的表现”,证明他们很有勇气,
>
> 当我退出的时候,某些人对我说:你不是男人,没勇气。我只是笑笑。
>
> 博彩,在我眼里,小赌也是赌,大赌也是赌,口头的打赌也是赌,
>
> 而随之而产生的赌博心理我不想有,这个算不得勇气,
>
> 请Eric.Wang稍微理智一点参与话题好吗?
>
> 我们是讨论,不是争论,也不是争论到最后站起来拍桌子之后面红耳赤的对我说:我敢和你打赌。用i++的绝对比++i的多。
>
> 就算你赢了又如何?你获得了什么?我赢了又如何?我又获得了什么?
>
> 答案很明显,什么都没获得,获得的只是你内心的某些报复性的“快感”而已。
>
> 我赢了,你输了,类似这样。
>
> 仍旧没有获得有价值的东西。
>

> 2009/5/3 LeeoNix <leeoni...@gmail.com>


>
> > 很不幸,我从不参与任何博彩类的活动。包括所谓的口头打赌,这个不符合我的价值观。
>
> > 打赌有意义吗?包括现实中争论的时候,面红耳赤的时候站起来就说:我敢和你打赌。类似这个如何如何。
>
> > 打赌是争论到了极端之后用的极端方法而已。
>
> > 你不能用代码数量去说明i++就是比++i如你意愿中的所谓的“优秀”。
>
> > 更不能用打赌的方式去解决这个问题。你很喜欢这个方式吗?
>

> > 2009/5/3 Eric.Wang <wangshaoq...@gmail.com>

LeeoNix

unread,
May 3, 2009, 10:48:05 AM5/3/09
to pon...@googlegroups.com
真的正为水贴了,习惯都成为“品味”了。计算机可不理会什么品味问题。

而你的品味证明了什么呢?我就问你这一个,你用品味二字参与这个话题,有什么意义?纯粹为了好玩?

2009/5/3 Eric.Wang <wangsh...@gmail.com>

LeeoNix

unread,
May 3, 2009, 10:53:22 AM5/3/09
to pon...@googlegroups.com
你看了“十几份”“优秀的开源项目”的代码,然后着眼看到的却是“i++”比“++i”用的多,并且“统计”了一下,

而你的兴趣和个人喜好却让这个话题跑掉了主题。

你所说的“优秀开源项目”代表不了i++用法的“优秀”和“品位”,就是所有开源项目也代表不了什么。

非得让大家都和你争论这个,不惜拿出了“打赌”这个杀手锏。

作为发表话题的人,我本人希望结束这个话题了。毫无意义,打赌都出来了。

2009/5/3 LeeoNix <leeo...@gmail.com>

Eric.Wang

unread,
May 3, 2009, 10:54:32 AM5/3/09
to TopLanguage
我认为一个好的程序员,应该都有对代码的良好品位。因为很多东西不是书上可以说清楚,或者规范可以规范明白的。

if (b) return;

if (b)
return;

if ()
{
return;
}

上面三种情况,何时用哪种比较好,就是一个没有绝对标准的问题。这就很考验程序员的品位。
有些公司会规定成第二种或者第三种,是为了避免坏的品位带来bad smell。但是很多好的代码也是写 if (b) return;的。


On 5月3日, 下午10时48分, LeeoNix <leeoni...@gmail.com> wrote:
> 真的正为水贴了,习惯都成为“品味”了。计算机可不理会什么品味问题。
>
> 而你的品味证明了什么呢?我就问你这一个,你用品味二字参与这个话题,有什么意义?纯粹为了好玩?
>

> 2009/5/3 Eric.Wang <wangshaoq...@gmail.com>

Eric.Wang

unread,
May 3, 2009, 10:56:37 AM5/3/09
to TopLanguage
好的,我尊重你作为帖主发的这个帖子。我会单独发帖讨论代码风格的问题。


On 5月3日, 下午10时53分, LeeoNix <leeoni...@gmail.com> wrote:
> 你看了“十几份”“优秀的开源项目”的代码,然后着眼看到的却是“i++”比“++i”用的多,并且“统计”了一下,
>
> 而你的兴趣和个人喜好却让这个话题跑掉了主题。
>
> 你所说的“优秀开源项目”代表不了i++用法的“优秀”和“品位”,就是所有开源项目也代表不了什么。
>
> 非得让大家都和你争论这个,不惜拿出了“打赌”这个杀手锏。
>
> 作为发表话题的人,我本人希望结束这个话题了。毫无意义,打赌都出来了。
>

> 2009/5/3 LeeoNix <leeoni...@gmail.com>


>
> > 真的正为水贴了,习惯都成为“品味”了。计算机可不理会什么品味问题。
>
> > 而你的品味证明了什么呢?我就问你这一个,你用品味二字参与这个话题,有什么意义?纯粹为了好玩?
>

> > 2009/5/3 Eric.Wang <wangshaoq...@gmail.com>

James Z.M. GAO

unread,
May 3, 2009, 11:12:30 AM5/3/09
to pon...@googlegroups.com
需要对状态设计一套编码, 和hash差不多, 状态一变, 跳转表就变了.
对于比较复杂的状态, 我有时候会用真值表设计跳转表(小项目),
但是稍微大一点的项目又不敢用, 因为别人理解不了, 给自己添麻烦, 呵呵,
另外不是性能瓶颈也没必要这么上心彻底消除分支.

这位兄台有什么消除分支的好经验分享吗?

On Sun, 3 May 2009, avalon xu wrote:

> 这个group正在沦落为水潭了。
> 记得以前讨论过国内外程序员的差异,国内外的mailing
> list就是个缩影,国外的好点的技术mailing list哪有这么多无聊的水贴。
> 真有时间或真有代码优化心得,就谈谈优化技术,比如我们以前做优化,为了消除分支

?? ??代码顺序执行,在运行时根据状态动态生成代码然后跳转执行...我不觉得i++和++i会
?? ??程序性能有什么改变。
> 当初这个group吸引我的地方是里面经常讨论一些小的算法问题,我很喜欢在平时不忙
?? ??时候思考一些数学小问题来消磨时间.不过现在这点乐趣也找不到了,我觉得pongda应该对topic的质量做些管理了,这种水
?? ??直接删除的好, 没啥好讨论的。
>
>
>
>

avalon xu

unread,
May 3, 2009, 12:04:31 PM5/3/09
to pon...@googlegroups.com
我不清楚跳转表是指的什么,能否具体举例说说?如果是类似 jmp xxx,可能和我说的不是一回事。我说的是动态生成代码指令,比如  if ( condition1)  S = A+B;  这里我们有个动态编译的过程,根据当前的condition1状态,生成S=A+B的机器指令,这对于外层很频繁调用的代码片段而言还是很有用的。
如果用跳转表的话,可能优点是便于维护吧,上层的程序写起来也比较养眼?

2009/5/3 James Z.M. GAO <gao...@gmail.com>
需要对状态设计一套编码, 和hash差不多, 状态一变, 跳转表就变了.

Tiny fool

unread,
May 3, 2009, 12:15:45 PM5/3/09
to pon...@googlegroups.com
你这里的condition1是一个静态条件还是一个动态条件?

2009/5/4 avalon xu <aval...@gmail.com>



--
--------------
Gmail: tiny...@gmail.com
Gtalk:   tiny...@gmail.com
Phone: 13520711089
Twitter:http://twitter.com/tinyfool

银杏泰克科技有限公司-专业的站内搜索引擎提供商
http://www.ginkgotek.com/

Tinyfool的开发日记
http://www.tinydust.net/prog/diary/diary.htm

TV的Google观察
http://www.tinydust.net/tinygoogle/

Zhiming G

unread,
May 3, 2009, 12:27:04 PM5/3/09
to pon...@googlegroups.com
虽然偏离了此帖主线, 还是想问一下, 用什么语言, 怎么动态生成代码? 动态写.text段, 还是加载动态库, 还是修改ip指针?

我以前弄过的都比较初级, 用switch或者函数指针数组, 说白了也是jmp/call, 地址是很多condition综合起来计算得出的结果, 计算过程尽量减少指令, 比如将比较结果通过位运算得出一个整数作为偏移量.

2009/5/4 avalon xu <aval...@gmail.com>

avalon xu

unread,
May 3, 2009, 12:37:33 PM5/3/09
to pon...@googlegroups.com
动态,不过处在优化状态(编译)时,是相对静态的了,不会改变了。


2009/5/4 Tiny fool <tiny...@gmail.com>

avalon xu

unread,
May 3, 2009, 12:37:38 PM5/3/09
to pon...@googlegroups.com
c语言,代码主要是生成SSE指令,写的话,应该是填入VitualAlloc的mem, n年前的东西了,其实早就忘光了~


2009/5/4 Zhiming G <gao...@gmail.com>

Zhiming G

unread,
May 3, 2009, 12:48:48 PM5/3/09
to pon...@googlegroups.com
指令是在运行时编译生成的吗(文本->指令), 还是预先设计好的(很多Magic Number), 在运行时拼成需要的指令序列? 

2009/5/4 avalon xu <aval...@gmail.com>

张慧聪

unread,
May 3, 2009, 2:46:36 PM5/3/09
to pon...@googlegroups.com


2009/5/3 Roof <roofa...@gmail.com>

++i呢,就是把i增加1
两个说法如同“他自杀”和“打死他”一样,其实最后公说公有理,婆说婆有理,我认为对两个写法最好采取宽容态
度,除非小组已经定义了一定要用哪个。

OT一个,C++权威人士称,C语言的语义专家坚持认为C++其实应该叫++C

CoreWar

unread,
May 3, 2009, 7:55:39 PM5/3/09
to TopLanguage
嗯,代码自生成

以前做过类似的工作,也是拿MMX/SSE优化东西,不过我们是首先写好所有的情况,大概有2、30个函数的样子,
然后根据条件动态生成一个函数表,执行起来一层层跳过去就可以了,省掉了判断跟call的开销。

Mea Culpa

unread,
May 3, 2009, 10:57:31 PM5/3/09
to pon...@googlegroups.com

我只知道目前的软件工程理论体系
以行数量化程序员工作量居多
所以程序员永远应该选择第三种,
程序员是工人,工人的天职是劳动力成本最大化。

可读性一定要高,行数一定要多;
尽量杜绝一行2个以上运算符,杜绝递归嵌套和迭代

--
=================
Holier Than Thou!
=================

qiaojie

unread,
May 3, 2009, 11:23:23 PM5/3/09
to pon...@googlegroups.com
杜绝一行2个以上运算符?

那么好吧,for里有三个运算符
for(int i = 0; i < 10; i++)
{
}

是不是应该写成
for(int i = 0;
     i < 10;
     i++)


2009/5/4 Mea Culpa <infe...@gmail.com>

空气

unread,
May 3, 2009, 11:53:50 PM5/3/09
to TopLanguage
恩~受教了

On 5月2日, 下午9时19分, LeeoNix <leeoni...@gmail.com> wrote:
> 说明你还不是很了解现代的编译器。
>
> 你测试用VS2005,但是你还是不了解cl.exe的命令行和真正优化的地方。
>
> 另外,VS的Debug版本和Release版本是两样的,一定记住这一点。
>
> 我上米说得end(),在Debug版本是不会被优化的,而在Release版本的时候就会被彻底优化。
>
> 具体见Linker选项生成的命令行的区别。
>
> 2009/5/2 空气 <lct8...@gmail.com>
>
> > char a[] = "abcdef";
> > int size;
> > int i, j;
>
> > size = strlen(a);
> > for (j = 0; j < 10000000; j++)
> > for (i = 0; i < size; i++)
> > ;
>
> > processed in 0.140625 seconds
>
> > char a[] = "abcdef";
> > int size;
> > int i, j;
>
> > for (j = 0; j < 10000000; j++)
> > for (i = 0; i < strlen(a); i++)
> > ;
> > processed in 0.671875 seconds
>
> > 测试环境,VS2005
>
> > 或许应该说,"编译器有可能优化"?
>
> > 但我确实是没见过有优化的。
>
> > On 4月29日, 下午8时04分, LeeoNix <leeoni...@gmail.com> wrote:
> > > 你错了,是会优化成这样的,不信你可以看反汇编。
>
> > > 这个是一个事实。
>
> > > 编译器会判断循环体的。
>
> > > 2009/4/29 空气 <lct8...@gmail.com>
>
> > > > 《深入理解计算机系统》里面说过,类似于
> > > > for (int i = 0; i < function(); i++)
> > > > 这种东西编译器是不会优化成
> > > > size = function();
> > > > for (int i = 0; i < size; i++)
>
> > > > 原因在与function()里面可能会执行一些影响其他东西的操作,比如对一个全局变量递增。
> > > > 这样"优化之后"这个全局变量就不会每次递增。
>
> > > > 编译器优化的大前提是不能改变代码原本的语义。
>
> > > > On 4月29日, 上午2时29分, LeeoNix <leeoni...@gmail.com> wrote:
> > > > > 简单的for循环作为例子:
>
> > > > > vector<int> ivec;
> > > > > for(vector<int>::iterator it = ivec.begin(); it != ivec.end(); it++)
>
> > > > > 知道一些STL基础的都知道这个其实并不是最合理的方式。
>
> > > > > for(vector<int>::iterator it = ivec.begin(), last = ivec.end(); it !=
> > > > last;
> > > > > ++it)
>
> > > > > 区别就在于保存end()迭代器,和++的前缀式和后缀式。
> > > > > 而现在编译器优化功能很是强大,将后缀式优化为前缀式。end()这个,也会优化掉。
>
> > > > > 可以说,现在编译器已经很智能了。
>
> > > > > 虽然最被推荐的方式还是用for_each,不过我还是用的很少。
>
> > > > > 使用STL的迭代器的时候,我还是会选择上面我举的例子的后者。虽然代码量稍大,但胜在我可以有个好习惯。
>
> > > > > 哪怕写for(int i = 0; i < size; ++i) 我都是这么写的。
>
> > > > > 我不知道大家是怎么看待这种编译器优化,我认为好的习惯更重要一些。
>
> > > > > 看看大家的视角怎么看待这个事情。

居振梁

unread,
May 4, 2009, 1:56:31 AM5/4/09
to pon...@googlegroups.com
囧。

if()
{
}
else
{
}

一下就占了7行,来个两三个(简单条件的)if,外加一些必要的空行,看看一屏幕还能显示多少代码?
我实在不习惯这种严重浪费显示器空间的编码风格(写书的人这样写也大大增加了篇幅,但是却没带来同等的信息量)。

2009/5/4 Mea Culpa <infe...@gmail.com>

我只知道目前的软件工程理论体系
以行数量化程序员工作量居多
所以程序员永远应该选择第三种,
程序员是工人,工人的天职是劳动力成本最大化。

可读性一定要高,行数一定要多;
尽量杜绝一行2个以上运算符,杜绝递归嵌套和迭代



--
自学走了不少弯路,更浪费了太多的时间,寻找良师益友。
追求黑客精神和清心寡欲的心态。
http://wargrey.yo2.cn
http://wargrey.blogspot.com
主要兴趣:Unix/GNU Linux、人工智能、移动计算、虚拟化
其他兴趣:心理学、自然科学、数学、武术、自然语言

殷远超

unread,
May 4, 2009, 2:16:48 AM5/4/09
to pon...@googlegroups.com
我读起来还好,每个人确实有不一样的习惯,在这里大家最好能够宽容一点,如同你认为他应该对别人宽容点一样。其实对他的火气也可以宽容一点。这样就不会有争吵。至少我相信,这里每个人发言,都不会有恶意吧。

2009/5/3 Fei Yan <skyscr...@gmail.com>
有时间建议你找个其他人,仔细读一下你回复的内容,看看别人的第一反应是什么。

我只是善意的提醒你一下,你的回复让人感觉强烈的不舒服,很难让人感觉你是对事不对人的。

如果你确实是对事不对人,建议你(也包括我)仔细琢磨琢磨潜在的原因肯定是很有好处的,很多时候技术本身不是看起来那么的重要(当然也不是说不重要)。



2009/5/3 LeeoNix <leeo...@gmail.com>
我没质问你。或许你认为我口气大了。可是我说的对事不对人,请不要和你本人扯上关系。
 
如果代码很多,手工方式是大忌。所谓“累死人”的事情我只在编码的时候发现过。
 
我只是说一个习惯,并没有涉及到review这一块。
 
你说到review的时候,这个习惯是分团队的,不关什么习惯和风格,都是团队优先的。
 
并没有绝对化的公式。如果你认为你的编译器可以做到优化,怎么写是组织者考虑的方式。
 
当然for_each是好选择。

2009/5/3 Fei Yan <skyscr...@gmail.com>

火气这么大可不是什么好事情...
我只是陈述一种事实而已,现实中不带这么理想化的;coding standards我说遇见的也从来没有细化到这一步的...

扯上正则表达式、python/perl, 是一种质问别人弱智的口气...
不参与这种无意义的争论

2009/5/3 LeeoNix <leeo...@gmail.com>

累死人?
 
我不知道你code review是怎么用的。
 
要知道程序员一个永远都通用的规则:宁愿花时间做工具去做也不要花一秒钟手工去干。
 
grep是个很好的工具,类似的工具也很多。
 
脚本也是个很好的工具,尤其Python和Perl在处理文本的时候。
 
正则表达式是很强大的,lint是很有用的。
 
版本控制的差异,各种类型的比较工具都是有异议的,
 
真的会如你所说的“累死人”。
 
一个团队里保持一种风格就可以了,如果不被大家所认同,那花时间修改是绝对有必要的。

2009/5/3 skyscribe <skyscr...@gmail.com>

从求知的角度来讲,值得去搞清楚这些细节,本身没有多大坏处。

从实用的角度,写代码还是简洁明了的好。这种差异,在Review的时候,就是non-issue,没有对错。
我个人接触到的代码,从没有到需要优化这一块的地步。
纠结于此类细节上边,code review的时候岂不累死人?

On 5月2日, 下午10时46分, 殷远超 <yinyuanc...@gmail.com> wrote:
> 同意,事实上很多时候,前期的不必要优化成了后期的梦魇。我愿意去理解这两种之间的差别,在确认编译器不能优化,并且自己很在乎这一块效率的时候,才去优化。
> 无profile,不优化~
>
> 2009/4/30 Eric.Wang <wangshaoq...@gmail.com>
>
> > 我倾向于

> > vector<int> ivec;
> > for(vector<int>::iterator it = ivec.begin(); it != ivec.end(); it++)
>
> > 因为简洁明快,所见即所得。
>
> > 优化 is another case。
>
> > 一个程序里面,其实大部分代码都是不用优化的。为了这些不用优化的地方付出额外代价,其实就是损失。
>
> > 在需要优化的地方做优化。不需要优化的地方,就写得简洁明快一点,好维护。
>
> --
> 殷远超http://www.yinux.com







--
殷远超 http://www.yinux.com

殷远超

unread,
May 4, 2009, 2:25:25 AM5/4/09
to pon...@googlegroups.com

循环体外已经不是风格问题了,同时还有作用域问题。
不过如果编译器不支持,那当然只能选择用支持的方式,或者换编译器。呵呵
2009/5/3 LeeoNix <leeo...@gmail.com>
可是我的编译器不支持这个,约定好用C方式编译,出错。循环体外声明,就搞定。

gcc现在新的版本是不是支持c99标准了?

2009/5/3 James Z.M. GAO <gao...@gmail.com>
c89的确是. (c99可以"for(int i"的).

补充一个例子, 下面那个更直观易读呢:

=============================
{
 int f = foo(aaaaaaaaaaa,
           bbbbbbbbbbbbbbbbb,
           cccccccccccccccc,
           ddddddddddddddddd,
           eeeeeeeeeeeeeeeeee);

 for(int i = 0; i < f; i++);
}

===============================

for(int i = 0; i < foo(aaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbb,ccccccccccccc,ddddddddddd,eeeeeeeeeee); i++);

===============================

我想多一个变量(第一种写法)更易读了吧~




On Sun, 3 May 2009, LeeoNix wrote:

定一个int绕一个弯?如果你用纯C的代码

for( int i =0; ;)
这样都不给你用的。

只能int i;
for( i = 0; ; )

由不得你不定义,当定义一个i的时候,可以一起定义一个size。

int i, size = strlen(s);
for (i =0; i< size; ++i)

这样的,适合在纯C代码运行的,是否符合你的审美观呢?




--
殷远超 http://www.yinux.com

missdeer

unread,
May 4, 2009, 6:23:31 AM5/4/09
to TopLanguage
老大,不要断章取义或者偷换概念,我已经很明确说了我的前提和限制"在我看来大多数时候,循环体是一段独立的逻辑"。
你硬要说定义functor方便不方便,那我说一个程序把所有代码都写在main里不是更方便。
至于访问其他变量,你可以传进去,你可以for_each里用method而不是functor来访问成员变量,途径是很多的。

On May 3, 10:06 pm, qiaojie <qiao...@gmail.com> wrote:
> 无法理解在C++用for_each代替for能得到什么好处。难道定义functor很方便吗?在我看来那就是把一段本是高内聚的代码拆分的七零八落。如果f or_each内需要访问外面的变量又怎么办呢?难道都传到functor对象里去?多么别扭啊
> missdeer 能不能举几个例子,让我看看for_each代替for的好处?
>
> 2009/5/3 missdeer <missd...@gmail.com>
>
> > 如果单纯从代码风格考虑的话,我一般倾向于用for_each甚于for,在我看来大多数时候,循环体是一段独立的逻辑,提取成一个functor或一
> > 个method很合理而且有必要,如果代码实在短得可以,就用boost::lambda凑合一下。

It is loading more messages.
0 new messages