写了一个编译期执行的fibonacci模板:
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;
把每一个值都给缓存下来了,效率当然高了,我们使用相同的缓存策略也可以缩短函数的运行时间。
编译期执行的函数则没有这个优点,它和普通的函数没有区别,不同点在于它在编译的时候运行。把编译器看成一种动态语言运行环境,那么编译“编译期执行的函数”的过程就像是运行动态语言程序的过程。如果程序中存在大量编译期执行函数,可能极大地降低编译效率,对于它的使用应该尽量避免。
模板提供的是一种声明式语法,在复杂的静态执行逻辑面前有时候会显得力不从心,编译期执行函数在解决这个问题的同时,却带来了上面这种副作用。如果能把两者的优点结合起来,用函数的语法来写程序,由编译器生成优化的模板代码,这种编译期执行才可以大量使用。
分享到:
相关推荐
其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。 Rust 语言由 Mozilla 开发,最早发布于 2014 年 9 月。Rust 的编译器是在 MIT License 和 Apache License 2.0 ...
ant是一种针对对象的动态语言,变量和函数均完全支持动态类型,但julia,变量和函数的形参均可以进行显示的类型标记,这不光可以带来编译期的类型检查,还可以删除执行例程的对象类型检查,从而可以显着提高程序的...
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 (3) 从堆上分配,亦称动态内存...
preparedstatement:叫做预编译的对象,在语句执行之前,向数据库发送类似于公式一样的模板,其中使用了替换变量,从而提高了数据存储的安全性,但这个数据操作对象不是效率最高的。可以应用于绝大多数数据库。 ...
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 (3) 从堆上分配,亦称动态内存...
第10章 早期(编译期)优化 10.1 概述 10.2 Javac编译器 10.2.1 Javac的源码与调试 10.2.2 解析与填充符号表 10.2.3 注解处理器 10.2.4 语义分析与字节码生成 10.3 Java语法糖的味道 10.3.1 泛型与类型擦除...
volatile指示字段可由操作系统、硬件或并发执行的线程等在程序中进行修改。 9,语句 语句是程序指令。除非特别说明,语句都按顺序执行。C# 具有下列类别的语句。 类别C# 关键字 选择语句if, else, switch, case 迭代...
存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。 1.9.2 准备 create table t_user ( username varchar2(20), ...
<<page 1>> page begin==================== 目 目目 目 录 录录 录 第一部分 C#语言概述.4 第一章 第一章第一章 第一章 .NET 编 编 ... 比尔....这一天 微软公司正式推出了其下一代...
/ 246 9.3.2 思路 / 247 9.3.3 实现 / 248 9.3.4 验证 / 255 9.4 本章小结 / 256 第四部分 程序编译与代码优化 第10章 早期(编译期)优化 / 258 10.1 概述 / 258 10.2 Javac编译器 / 259 10.2.1 Javac的...
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 三、从堆上分配,亦称动态内存分配...
其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言可能有所差异,所以不易移植。 C语言是一种结构化的高级语言。其优点是可读性好,移植容易,是普遍使用的一种计算机语言。缺点是占用资源较多...
并结合工作实践,实现了文本文档数据、Excel数据以及地理空间数据的批量处理,并对批处理代码进行可执行文件编译,方便了数据处理工具的共享应用,大大提高了工作效率,为数据批处理提供了切实可行的实践思路。...
执行期类型信息(RTTI) 动态生成(Dynamic Creation) 异常处理(Exception Handling) Template Template Functions Template Classes Template的编译与链接 第3章 MFC六大关键技术之仿真 MFC类层次结构 Frame 1...
这提供了一种很好的使用 SqlHelper 类来执行命令的模式,同时为开发人员选择访问数据的方式提供了必要的灵活性。每种方法的重载都支持不同的方法参数,因此开发人员可以确定传递连接、事务和参数信息的方式。类中...
ExecuteReader:此专用 ExecuteReader 实现用于通过适当的 CommandBehavior 打开 SqlDataReader 对象,以便最有效地管理与阅读器关联的连接的有效期。 SqlHelperParameterCache 类实现详细信息 参数数组缓存在专用 ...
答:软件生存周期模型是描述软件开发过程中各种活动如何执行的模型。 主要模型包括:瀑布模型、增量模型、螺旋模型、喷泉模型、变换模型和基于知识的模型。 5. 有哪些主要的软件开发方法? 答:主要的软件开发...
处理可包括使用汇编程序、编译程 序、解释程序或翻译程序来作为程序的执行作准备,以及执行该程序。 3.6 文档(文件):与程序开发、维护和使用有关的材料,它是软件的重要组成部分。 3.7 软件验证:为确保某一阶段...
引擎每次编译,每次生成的保护文件均不相同,从理论上杜绝了通用脱壳机和脱壳脚本的出现。 反函数挂钩. Anti-Hook 技术可以有效保护您的文件不被外部程序挂钩函数,例如外挂程序。 插件与 Lua 脚本扩展. 丰富的第...
这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。 2.4.增量收集器 增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。 2.5.分代收集器 这种收集器把堆栈...