d-编译时函数的记忆



我想懒洋洋地评估函数。由于计算返回值的成本很高,我必须使用内存化,尤其是对于被称为子函数的子函数,否则计算的时间复杂性将呈指数级爆炸。我需要编译时的结果。(我正在编写一个库,它根据提供的字符串提供各种编译时模板。)因此,简而言之,我需要在编译时进行内存化。

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一次与两次):

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

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

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

有什么方法可以记忆CT功能吗?

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

你的模板参数函数只会实例化一次,但每次都会运行

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进行注释,编译时间是相同的。

相关内容

  • 没有找到相关文章

最新更新