原创作者: qiezi
阅读:1185次
评论:0条
更新时间:2011-05-26
写了一个编译期执行的fibonacci模板:
D语言新支持的编译期执行函数也可以完成:
这2种实现,我原想编译效率应该都比较低,因为编译期执行是要花编译时间的。结果前一种编译效率非常高,后一种则比较低。仔细想想,的确应该是这样,这与模板产生代码的机制有关。
模板在实例化时,会根据参数产生出不同的代码。比如上面的第一个例子,fibonacci!(1)和fibonacci!(2)就会实例化出2份代码,所以fibonacci!(40)相当于产生了这样一组代码:
把每一个值都给缓存下来了,效率当然高了,我们使用相同的缓存策略也可以缩短函数的运行时间。
编译期执行的函数则没有这个优点,它和普通的函数没有区别,不同点在于它在编译的时候运行。把编译器看成一种动态语言运行环境,那么编译“编译期执行的函数”的过程就像是运行动态语言程序的过程。如果程序中存在大量编译期执行函数,可能极大地降低编译效率,对于它的使用应该尽量避免。
模板提供的是一种声明式语法,在复杂的静态执行逻辑面前有时候会显得力不从心,编译期执行函数在解决这个问题的同时,却带来了上面这种副作用。如果能把两者的优点结合起来,用函数的语法来写程序,由编译器生成优化的模板代码,这种编译期执行才可以大量使用。
template fibonacci(long n){ static if(n <= 2) const long fibonacci = 1; else const long fibonacci = fibonacci!(n-1) + fibonacci!(n-2); } static long a = fibonacci!(40);
D语言新支持的编译期执行函数也可以完成:
long fibonacci(long n){ if (n <= 2) return 1; return fibonacci(n-1) + fibonacci(n-2); } static long a = fibonacci(40);
这2种实现,我原想编译效率应该都比较低,因为编译期执行是要花编译时间的。结果前一种编译效率非常高,后一种则比较低。仔细想想,的确应该是这样,这与模板产生代码的机制有关。
模板在实例化时,会根据参数产生出不同的代码。比如上面的第一个例子,fibonacci!(1)和fibonacci!(2)就会实例化出2份代码,所以fibonacci!(40)相当于产生了这样一组代码:
// .... const long fibonacci_38 = fibonacci_37 + fibonacci_36; const long fibonacci_39 = fibonacci_38 + fibonacci_37; const long fibonacci_40 = fibonacci_39 + fibonacci_38; static long a = fibonacci_40;
把每一个值都给缓存下来了,效率当然高了,我们使用相同的缓存策略也可以缩短函数的运行时间。
编译期执行的函数则没有这个优点,它和普通的函数没有区别,不同点在于它在编译的时候运行。把编译器看成一种动态语言运行环境,那么编译“编译期执行的函数”的过程就像是运行动态语言程序的过程。如果程序中存在大量编译期执行函数,可能极大地降低编译效率,对于它的使用应该尽量避免。
模板提供的是一种声明式语法,在复杂的静态执行逻辑面前有时候会显得力不从心,编译期执行函数在解决这个问题的同时,却带来了上面这种副作用。如果能把两者的优点结合起来,用函数的语法来写程序,由编译器生成优化的模板代码,这种编译期执行才可以大量使用。
评论 共 0 条 请登录后发表评论