代码膨胀

KOL,不知道有多少朋友知道这个东西。它是一个VCL的替代品。如果你连VCL也不知道,也没关系,VCL是Delphi的标准库,提供全方面的功能。KOL的作者认为使用VCL写出来的程序太庞大了,所以他编写了KOL,并且成功的给出了现有技术下的解决方案。KOL的主页位于:http://bonanzas.rinet.ru/

KOL,其实并不是我喜欢的库。可能是因为里面用的奇技淫巧太多了吧。12k的GUI程序根本不能打动我,至少我还用过Win32Asm,用过WTL。但是我关心一点就是,KOL如何使得代码尺寸如此小的,那些“垃圾”代码是如何剔除的。关于这个问题我在一篇赞誉KOL的文章中找到了部分答案:http://bonanzas.rinet.ru/art002.htm。其实对于代码是如何膨胀的,自从我认识了汇编,认识了OOP的本质之后,就开始一直在思考了。先让我们来看看文章作者是怎么说VCL如此庞大的吧。

作者认为VCL如此庞大的主要原因有两个:1、无用虚函数不能通过Smart Linking技术剔除。2、过早的构造成员。这是我对作者观点的精练,稍微解释一二吧。Smart Linking是Delphi优化技术,它能够把没有用到的类以及非虚函数从最终的代码中剔除。这是一个链接技术,所以它没有办法干预类的V表,所以对于虚函数是无能为力的。所以普通的成员函数和全局函数如果没有用到,则不会进入最终的代码。而虚函数则一旦类被引用,则自身必然也要包含进入,更糟糕的是虚函数中引用的其他类也要一同包含进去,而那些类的虚函数又要再继续这个过程。对于第二点起初倒还真的没有想到它是可以避免代码膨胀的。一般情况下采用Lazy Load是为了加快对象的创建速度。当时认为成员变量所用的类带来的代码膨胀不可避免一是因为其他编译器不能做这样的Smart Linking,另外一个就是析构函数必然要引用成员变量的析构函数。但是在Delphi中,通过TObject的虚函数Free,可以避免对析构函数的直接调用。而且Delphi拥有Smart Linking技术。这样如果有一个成员Font: TFont。只要所有的引用都通过GetFont来进行,而第一次调用GetFont时才对Font进行创建。这样不调用GetFont,TFont的代码就不会被包括进来。

可以看出编译器和链接器的优化技术是减少代码尺寸的利器。Delphi或者说Pascal的Smart Linking使得KOL的奇技淫巧得以施展。而之前我也只是听说过Function Level Linking,没有Delphi的彻底。而文章中也提到,剔除无用的虚函数是可能的。或许通过全局分析,这种优化的确是可能的。但是细想一下,现在已经不是静态的天下了。动态语言的反射或许会对这种优化技术造成障碍也不一定。

再来批判批判KOL。它为了避免使用虚函数,放弃了强类型。把所有的控件类型用一个TControl全部搞定了。我觉得代码膨胀带来的rubbish code占用内存,CPU时间,网络带宽是有代价的,但是这样的对OOP的回退代价是更大的。可以说是得不偿失的。

最终是我的观点:
1、代码膨胀是应该避免的,虽然不一定是用剔除无用代码,也可能是共享库或者网格计算。因为无用的代码占用着内存,CPU时间和网络带宽。
2、代码膨胀的解决应该分析其根源。函数库时代,Function Level Linking就能解决问题。而OOP时代呢?不知道这里提到的两个原因是不是就是所有根源了。
3、最终的措施是要权衡的。毕竟现在流行的观点是代码尺寸和运行速度都是无关紧要的,装不下可以加硬盘,跑不起来可以加CPU加内存,硬件的改善总是比软件改善要容易要直接。为了一点点(从某种角度来说是如此)字节上的节省,使得开发变得步履蹒跚,则是得不偿失。始终要以开发能为客户创造价值的软件为目标,而不是开发什么尺寸最小的软件为目标。

你可能感兴趣的:(代码)