2009年4月份,我们的TTCN3新执行器大体功能已经完成了,于是找了几个项目来试点应用。
应用效果不太理想,特别是对于5万行以上的脚本工程,且包括大asn文件的情况。
新执行器转换出来的C++代码量很大,特别是由于asn类型很多,导致hpp文件代码量大的编译速度下降严重问题。
当时的数据大概是这样的,大asn文件存在5千多个不同的类型(约5万行),包括简单和复杂类型,
平均每个类型转换后的hpp代码量,约20行,合计超过1万行的hpp文件,全编译一次约30分钟时间(30万代码量),用户不接受。
我们曾经考虑过windows的pch方法来加快编译速度,但不可行,因为用户类型是可变的。
最后,只能从转换的hpp代码入手,看看那些可以省略的。
当时一个类型包括的成员函数大概如下:
1、默认构造函数
2、参数为基类的构造函数
3、拷贝构造函数
4、赋值操作函数
5、参数为基类的赋值操作函数
6、静态clone函数
7、析构函数
从上面的成员函数来看,已经很精简的了,用于比较操作的函数已经直接在基类中实现。
但我们还是发现了一个问题,就是构造函数和赋值函数使用过多,
这样做的原因,是为了简化转换器的逻辑,譬如:
var myType t1;
var myType t2 := t1; //这里转换后的C++代码可以通过拷贝构造函数实现
t2 := t1; //这里转换后的C++代码可以通过赋值操作函数实现
正因为C++支持操作符号重载,所以可以很方便的简化转换器的处理逻辑。
但也是因为这个问题,导致构造函数和赋值操作函数滥用,hpp文件过大,编译速度下降。
于是,我们重复问自己,这真的有必要嘛?
当然没有必要,其实所有这些都可以简单通过使用一个虚函数实现,如
virtual bool assignValue(const& baseType);
简单来说就是,转换器需要使用assignValue代替=符号,于是拷贝构造和赋值操作函数都不需要了。
由于assignValue的参数是基类引用,所以一个函数就可以搞定多种情况。
就这样,原来一个类需要20行的hpp代码量,现在下降到10行,编译性能提升2倍(这也验证了hpp文件对编译速度影响很大)。
这个方案将大工程的编译速度从30分钟下降到10分钟,
但后来我们找到一个更根本的方法,从而有从10分钟下降到3分钟,后续再说。