`
qiezi
  • 浏览: 491502 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

编译期执行的效率

    博客分类:
  • D
阅读更多
写了一个编译期执行的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;


把每一个值都给缓存下来了,效率当然高了,我们使用相同的缓存策略也可以缩短函数的运行时间。

编译期执行的函数则没有这个优点,它和普通的函数没有区别,不同点在于它在编译的时候运行。把编译器看成一种动态语言运行环境,那么编译“编译期执行的函数”的过程就像是运行动态语言程序的过程。如果程序中存在大量编译期执行函数,可能极大地降低编译效率,对于它的使用应该尽量避免。

模板提供的是一种声明式语法,在复杂的静态执行逻辑面前有时候会显得力不从心,编译期执行函数在解决这个问题的同时,却带来了上面这种副作用。如果能把两者的优点结合起来,用函数的语法来写程序,由编译器生成优化的模板代码,这种编译期执行才可以大量使用。
分享到:
评论
2 楼 qiezi 2007-03-15  
应该也不用这么复杂。只要把编译期执行函数的参数和返回值缓存就可以了,比如已经计算过fibonacci(5),再计算fibonacci(7)的时候就可以利用这个值了,模板用的也是这个原理,自己做缓存时也差不多。当然编译期执行函数也不可能完全取代模板的计算功能。
1 楼 oldrev 2007-03-15  
我觉得最佳办法是,把需要编译器执行的代码编译为IL格式的 obj 文件缓存起来,如果代码没变化就一直用 obj 文件中的就行了。

相关推荐

    Rust语言教程.docx

    其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。 Rust 语言由 Mozilla 开发,最早发布于 2014 年 9 月。Rust 的编译器是在 MIT License 和 Apache License 2.0 ...

    ant:ant是一种高效率的面向对象的并行多种语言,目标是多机分布式并行编程像单机串行编程一样高效简单丝滑。通过简单的编程和程序执行,即可以替换的调度成千上万台计算机并行执行程序并且不用在意向并行带来的执行顺序问题。 ant的指令端和代码的执行端完全分离,且ant可以享受多机跨语言分布式并行编程的乐趣

    ant是一种针对对象的动态语言,变量和函数均完全支持动态类型,但julia,变量和函数的形参均可以进行显示的类型标记,这不光可以带来编译期的类型检查,还可以删除执行例程的对象类型检查,从而可以显着提高程序的...

    踏入C++中的雷区C++内存管理详解

    在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。  (3) 从堆上分配,亦称动态内存...

    java实训题库(盗版必究)

    preparedstatement:叫做预编译的对象,在语句执行之前,向数据库发送类似于公式一样的模板,其中使用了替换变量,从而提高了数据存储的安全性,但这个数据操作对象不是效率最高的。可以应用于绝大多数数据库。 ...

    C++学习代码(实例)

    在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。  (3) 从堆上分配,亦称动态内存...

    Java虚拟机

    第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 泛型与类型擦除...

    c#学习笔记.txt

    volatile指示字段可由操作系统、硬件或并发执行的线程等在程序中进行修改。 9,语句 语句是程序指令。除非特别说明,语句都按顺序执行。C# 具有下列类别的语句。 类别C# 关键字 选择语句if, else, switch, case 迭代...

    SQL培训第一期

    存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。 1.9.2 准备 create table t_user ( username varchar2(20), ...

    C#微软培训资料

    &lt;&lt;page 1&gt;&gt; page begin==================== 目 目目 目 录 录录 录 第一部分 C#语言概述.4 第一章 第一章第一章 第一章 .NET 编 编 ... 比尔....这一天 微软公司正式推出了其下一代...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 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的...

    电子类软硬件面试集锦

    在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 三、从堆上分配,亦称动态内存分配...

    c语言编写单片机技巧

    其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言可能有所差异,所以不易移植。 C语言是一种结构化的高级语言。其优点是可读性好,移植容易,是普遍使用的一种计算机语言。缺点是占用资源较多...

    基于Python的数据批处理探讨与应用.docx

    并结合工作实践,实现了文本文档数据、Excel数据以及地理空间数据的批量处理,并对批处理代码进行可执行文件编译,方便了数据处理工具的共享应用,大大提高了工作效率,为数据批处理提供了切实可行的实践思路。...

    深入浅出MFC-简体版(2)PDF

    执行期类型信息(RTTI) 动态生成(Dynamic Creation) 异常处理(Exception Handling) Template Template Functions Template Classes Template的编译与链接 第3章 MFC六大关键技术之仿真 MFC类层次结构 Frame 1...

    SQLHelper.cs

    这提供了一种很好的使用 SqlHelper 类来执行命令的模式,同时为开发人员选择访问数据的方式提供了必要的灵活性。每种方法的重载都支持不同的方法参数,因此开发人员可以确定传递连接、事务和参数信息的方式。类中...

    .net数据访问类 SQL Helper 类

    ExecuteReader:此专用 ExecuteReader 实现用于通过适当的 CommandBehavior 打开 SqlDataReader 对象,以便最有效地管理与阅读器关联的连接的有效期。 SqlHelperParameterCache 类实现详细信息 参数数组缓存在专用 ...

    软件工程-理论与实践(许家珆)习题答案

    答:软件生存周期模型是描述软件开发过程中各种活动如何执行的模型。 主要模型包括:瀑布模型、增量模型、螺旋模型、喷泉模型、变换模型和基于知识的模型。 5. 有哪些主要的软件开发方法? 答:主要的软件开发...

    计算机软件行业审核作业指导书.doc

    处理可包括使用汇编程序、编译程 序、解释程序或翻译程序来作为程序的执行作准备,以及执行该程序。 3.6 文档(文件):与程序开发、维护和使用有关的材料,它是软件的重要组成部分。 3.7 软件验证:为确保某一阶段...

    软件保护专家 Zprotect 1.4.8

    引擎每次编译,每次生成的保护文件均不相同,从理论上杜绝了通用脱壳机和脱壳脚本的出现。 反函数挂钩. Anti-Hook 技术可以有效保护您的文件不被外部程序挂钩函数,例如外挂程序。 插件与 Lua 脚本扩展. 丰富的第...

    resin-jvm 调优

    这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。 2.4.增量收集器 增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。 2.5.分代收集器 这种收集器把堆栈...

Global site tag (gtag.js) - Google Analytics