MyException - 我的异常网
当前位置:我的异常网» VC/MFC » 关于MFC消息映射表与虚函数的效率有关问题

关于MFC消息映射表与虚函数的效率有关问题

www.myexceptions.net  网友分享于:2013-03-19  浏览:50次
关于MFC消息映射表与虚函数的效率问题
深入浅出MFC对于虚函数实现方式的缺点,它指出:虚函数耗费大量内存,系统最终将被这些额外负担拖垮。

  但是现在对于容量巨大的白菜价格的内存来说,这种额外负担是否已经过时了呢~?
  书中提到,虚函数表中的每一个项目都是一个函数指针,价值4字节,如果基类的虚函数表有100项 (MFC里面的消息数量是否在这个数量级?),经过十层继承,开支散叶,总共需要耗费多少内存?
  我粗略地算了下,不知道这种计算方法是否正确,4Byte*100项=400Byte。如果CCmdTarget中定义100个消息,那其中虚函数表字段大约要占用400字节的内存。
  然后我数了下,MFC中派生自CCmdTarget的类总共有100个,那么这么多类的虚函数表总共需要占用多少个字节呢?
  400Byte*100个=40KB字节。
  然后加上 程序员自己派生的类和消息 所多占的函数指针项,我想也应该不会超过40KB这个基础内存空间的10倍吧?也就是不超过400KB字节的内存。
  然而现在动辄几G的内存,这点消耗大概应该可以忽略不计吧?
   
  所以,我的问题是,如果如书上所说,虚函数的实现方案增加了太多的额外负担,那我以上的计算方法哪里出错了?
  如果我的上述讨论方法正确的话,那是否能说明书上的说法已经过时,而利用虚函数的实现方法,用空间换取执行效率上的提高可行呢?

------解决方案--------------------
楼主的想法是很好的,我觉得候捷的说法也有点言过其实,用虚函数来实现消息处理,Delphi和;C++Builder本身就是这么做的,所以个人认为完全可行。而且显然Delphi的VCL用的技术要比MFC先进,关于Delphi的处
理机制可以看一下李维的《inside vcl》(即 深入核心——vcl架构剖析)。

虚函数表应该不会是简单的4Byte的函数指针这么简单,这个不是很清楚。

别外我觉得 每一个类对象比他可见的字节多一个虚函数表的大小 并不是指每一个对像都要对应一个虚函数表

------解决方案--------------------
楼主说的没错。
而且你的程序中不太可能把MFC中全部的类都用到。对于那些没有用到的类,当然就不会需要它们所需的虚表空间(即使是选择动态连接MFC库,那也是各个使用MFC的程序共享系统中同一份mfcxx.dll的物理拷贝——映射到各个进程自己的地址空间而已)。
至于说每个对象都要浪费4字节的指向虚表的指针,这个是没有办法的,这是实现多态的代价(这里特指运行时多态)。任何一种语言,只要它想从语言的级别上支持多态,所需要的代价都不太可能比这个更低。如果你用C语言模拟一下多态,就会对这一点更清楚,空间开销不太可能比这更少。
另外,拥有多态行为的对象,往往都是一些负责上层业务逻辑的对象,这样的对象通常不会在程序中大量存在,既使数量稍微多一些,可能每一个对象的生存期也不会很长。它们不会像CString那样,可能需要在程序中长时间大量存在,以致于空间的开销可能造成不可忽略的浪费,但问题是像CString这样的功能具体的util类,通常是不需要有多态行为的,也就不需要有虚函数。
另外,在JAVA中,除了静态函数和private函数之外,所有的类的成员函数默认就是virtual的。但JAVA不也照样构造了许多大型的企业级应用么。
------解决方案--------------------
所以,如果要在虚函数方面评论一下MFC的设计,不应该把着眼点放在虚函数的空间开销方面。而应该想:MFC中有没有什么东西在不需要使用虚函数的时候却使用了虚函数。如果没有,那就是没啥问题的。
写代码不都是为了解决某种需求么,所以只要别在不需要的时候使用就OK。
------解决方案--------------------
虽然基类有几百个虚函数是太夸张了些。
不过以现在的硬件水平,这点内存消耗不算什么了,写个.net的小程序,什么都没干呢,
看看内存消耗,加起来已经过20兆了。
------解决方案--------------------
.net框架的DLL是各个进程共享的,MFC的也一样,除非静态链接。
MFC的消息映射还有对最近收到的消息的映射做缓存,这点用switch和虚函数表做不到。
注意消息映射不光是有调用消息处理函数,还有一个消息分发的过程。
------解决方案--------------------
我个人的机器4G内存,工作机器64G,除非定义对象的个数真的达到那么海量的情况下,4字节每对象的内存损耗才需要费劲去思考,但是这种情况毕竟是很少的。
况且,映射表方式省内存的前提是你海量类型、对象都没有虚表,也就是每个类都不允许虚函数,这即使在MFC中也是不可能的。最基本的,如果一个类希望由基类指针来删除,虚析构函数是不可避免的。从这点上来讲,把“映射表”和“虚函数”对立本来就是一个假命题,至少在MFC中,所有在message map中涉及的类都是用了虚函数的,使用“映射表”根本没有节省所谓虚表所省下来的内存,因为虚表总还是定义了。

------解决方案--------------------
虚函数的个数对这个问题几乎是没有贡献的,因为每个“类”是一个虚表,几百个虚函数最多也就多占有最多k级的内存而已,几乎毫无消耗
探讨
虽然基类有几百个虚函数是太夸张了些。
不过以现在的硬件水平,这点内存消耗不算什么了,写个.net的小程序,什么都没干呢,
看看内存消耗,加起来已经过20兆了。

------解决方案--------------------
探讨
虚函数的个数对这个问题几乎是没有贡献的,因为每个“类”是一个虚表,几百个虚函数最多也就多占有最多k级的内存而已,几乎毫无消耗
引用:
虽然基类有几百个虚函数是太夸张了些。
不过以现在的硬件水平,这点内存消耗不算什么了,写个.net的小程序,什么都没干呢,
看看内存消耗,加起来已经过20兆了。


------解决方案--------------------
探讨
我个人的机器4G内存,工作机器64G,除非定义对象的个数真的达到那么海量的情况下,4字节每对象的内存损耗才需要费劲去思考,但是这种情况毕竟是很少的。
况且,映射表方式省内存的前提是你海量类型、对象都没有虚表,也就是每个类都不允许虚函数,这即使在MFC中也是不可能的。最基本的,如果一个类希望由基类指针来删除,虚析构函数是不可避免的。从这点上来讲,把“映射表”和“虚函数”对立本来就是一个假命题,至少在MFC中,所有在message map中涉及的类都是用了虚函数的,使用“映射表”根本没有节省所谓虚表所省下来的内存,因为虚表总还是定义了。


------解决方案--------------------
探讨
侯捷的话在哪都灵验,这是没办法的事情,本质原因就在于虚表是跟随对象走的,而不是类。

文章评论

每天工作4小时的程序员
每天工作4小时的程序员
旅行,写作,编程
旅行,写作,编程
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
那些争议最大的编程观点
那些争议最大的编程观点
我的丈夫是个程序员
我的丈夫是个程序员
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
程序员都该阅读的书
程序员都该阅读的书
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
鲜为人知的编程真相
鲜为人知的编程真相
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
我是如何打败拖延症的
我是如何打败拖延症的
代码女神横空出世
代码女神横空出世
为什么程序员都是夜猫子
为什么程序员都是夜猫子
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
总结2014中国互联网十大段子
总结2014中国互联网十大段子
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
10个调试和排错的小建议
10个调试和排错的小建议
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
漫画:程序员的工作
漫画:程序员的工作
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
Java程序员必看电影
Java程序员必看电影
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员和编码员之间的区别
程序员和编码员之间的区别
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
老程序员的下场
老程序员的下场
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
一个程序员的时间管理
一个程序员的时间管理
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
中美印日四国程序员比较
中美印日四国程序员比较
编程语言是女人
编程语言是女人
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员必看的十大电影
程序员必看的十大电影
如何成为一名黑客
如何成为一名黑客
 程序员的样子
程序员的样子
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有