posts - 9,  comments - 9,  trackbacks - 0

有子曰:其为人也孝弟,而好犯上者,鲜矣;不好犯上,而好作乱者,未之有也。君子务本,本立而道生。孝弟也者,其为仁之本与。

                                                                                      --《论语今解·学而第一》

 若要达到一个目标,必须循其根本,根本如能确定(本立),那么便容易找出解决的方法(道生)。很多时候就是这样的道理,遇到一个问题,要追究到底才是,更何况是我们做技术的,记得第一次看见这个“本立道生”的词的时候是在候捷翻译的《Inside C++ Object Model》这个是作为他的序言的标题的。其实当你真的了解很多细节的时候你才能真正的体会到技术的魅力,而不是代码的奴隶!

 前几天去微软面试的时候,当时那个主考官问我什么叫overload operator()?以及如何区分它和callback?当时回答的时候,我是这么想的,我是没有用过这个仿函数啦,但是我知道仿函数是怎么实现的,就是通过重载operator()的方法实现的,而至于callback那么肯定就是通过函数指针去实现了。当时我的第一反应就是可能这个performance算是一个吧,我就这么说了,这个operator()可能是作为inline展开了,节省了函数调用的时间,提高了性能。  但是如果是callback的话,就不可能是作为inline展开了。当时也就这么回答了。主考官给我的回复是这样的,其实至于performance这一块来讲了,也不是最主要的影响,关键的地方在于这个operator()可以保存调用的状态或标志什么的私有数据,而callback只能用static的变量来取代,但是不好的还是static只能为所有的代码服务,而overload operator()可以为每一个obj保存私有数据部分。他说了,对的,显然他说的是没错。但是当时心中还是对他关于performance的回答有点疑虑,当时由于是在面试,也没有多想下去,后来仔细想来,其实最关键的还是这个performance,众所周知,如果一个class member function可以作成inline的属性的,当然编译器有权利决定在调用点是否内联展开,其实在大多数的情况下面,试想如下的代码情况:
 
Class Compare
{
public:
    bool operator (
int iFrst, int iSecond) const
   
{
    
// Do some thing
    return false// Or true
   
}

};


// SortList(List& list, int iSize, const Compare& compareObj)
SortList(list, 1000, com);

如上面的所示,这个class的重载的operator()显然就是带有inline的属性了,这个时候编译器能做的是在能够确定对象类型的时候如果这个代码不是太大(当然还要求你的编译器内联选项容许状态)那么就会在调用点内联展开。但是如果是callback呢?肯定不是,因为他用到了函数指针,即使是这个函数定义成了inline,这个时候也不会做内联展开的(这个时候会有生成一个类似全局的函数代码块,回掉的指针就指向这个块,编译器会维护这个代码块的唯一性)。所以,如果要是仿函数要求确保内联展开的会,要唯一确保的是,代码中的调用点应该是可以确定类型的,能够做内联展开。然后,这个仿函数大多数情况下是没有多态以及继承伴随左右的,所以这个performance是很重要的区别之一,尤其是在你需要处理大量的同类数据的时候,比如上面的这个例子,如果iSize很大,甚至是上万的,那么这个时候的performance估计差别就会太大了。也许你的CPU频率更高,但是更多的是可能是这个没有必要的损失。呵呵。

小提示:如何判断一个函数调用是否被内联展开?
方法:1.你当然可以生成汇编,自己去看。2.你可以在调用点设置断点,看看能不能跟进去?(内联的debug不能跟进去函数,至少目前我所知道的编译器是这样的)。3.当然更多的时候在调用点设置断点,然后查看汇编代码才是最权威的,也是比较简单的方法。
posted on 2007-04-18 15:30 MicroYang 阅读(541) 评论(2)  编辑 收藏 引用

FeedBack:
# re: 本立道生
2012-03-02 18:36 | 佚名
理解有误。函数对象可实现函数指针不能实现的功能才是主要的。  回复  更多评论
  
# re: 本立道生[未登录]
2012-04-01 16:42 | zxx
极端情况下,容器的size很大,inline带来的performance的提高不可忽视。但是问题问的是仿函数普遍的优点。能保存数据才是标准answer  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(1)

随笔档案

Friend

  • Catherine
  • 深海羚羊
  • 似雨打芭蕉,似风吹梧桐叶,带着一丝冰冷,也带着一丝清新------冰柔语丝

搜索

  •  

最新评论

阅读排行榜

评论排行榜