【问题标题】:Memoization for compile time functions编译时函数的记忆
【发布时间】:2016-07-15 01:20:15
【问题描述】:

我想懒惰地评估函数。由于计算返回值很昂贵,我必须使用记忆,特别是对于被调用的子函数,否则计算的时间复杂度会呈指数级增长。我需要编译时的结果。 (我正在编写一个库,它根据提供的字符串提供各种编译时模板。)简而言之,我需要在编译时进行记忆。

std.functional.memoize 不工作 CT,所以这是不可能的。 DMD 和 LDC 不够聪明,无法记忆纯函数,至少这是我对简单纯函数的实验结果:我测试它是否缓存结果的方式:

使用简单的参数:

int sumN(int n) pure {
    int result = 0;
    for (int i = 0; i<=n; i++) result += i;
    return result;
}

void main() {
    enum sumMany =    sumN(2000000);
    enum sumMany2 =   sumN(2000000);
    writeln(sumMany, " ", sumMany2);
}

使用模板参数:

int sumN(int n)() pure {
    int result = 0;
    for (int i = 0; i<=n; i++) result += i;
    return result;
}

void main() {
    enum sumMany =    sumN!2000000;
    enum sumMany2 =   sumN!2000000;
    writeln(sumMany, " ", sumMany2);
}

计时编译(调用 sumN 一次 vs 两次):

time dmd -O -release -inline -boundscheck=off repeatpure.d

time ldc2 -O5 -release -inline -boundscheck=off repeatpure.d

当我在源代码中有两个枚举时,编译时间总是两倍。

有没有办法记忆CT函数?

【问题讨论】:

    标签: d memoization compilation-time ctfe


    【解决方案1】:

    具有所有相同参数的模板只应实例化一次,因此您要做的是将结果设为模板本身内部的常量值(在本例中为枚举)。

    你的模板参数函数只会被实例化一次,但它会在你每次执行时运行。创建一个只运行一次的辅助函数:

    template sumN(int n) {
        int helper() {
            int result = 0;
            for (int i = 0; i<=n; i++) result += i;
            return result;
        }
    
        // this is run once per unique argument group
        enum sumN = helper();
    }
    
    void main() {
        // so both of these now reference the same constant
        enum sumMany =    sumN!2000000;
        enum sumMany2 =   sumN!2000000;
        writeln(sumMany, " ", sumMany2);
    }
    

    这并不完全是记忆,但它可能足以满足您的需要 - 请注意,如果您评论其中一个 sumMany,编译时间是相同的。

    【讨论】:

    • 正是我想要的!谢谢!
    • 一些非常重要的细节:helper() 必须在模板内。模板外的 int helper(int n) pure {...} 和从模板调用的速度与其他解决方案一样慢。 (为什么??)
    • Tamas:你确定吗?它不应该有什么不同,当我在这里尝试时确实没有。
    • 我错了。确实,没有区别。谢谢,对噪音感到抱歉!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2020-11-07
    • 2022-12-17
    • 2023-01-27
    • 1970-01-01
    • 2010-12-04
    相关资源
    最近更新 更多