如果我写
enum chars = digits ~ uppercase;字符串是否会在编译时连接起来?我猜它会的。如果我将其替换为字符串文字或CTFE函数,我无法测量任何显着的性能差异(即使调用它一亿次)。如果我用const替换枚举,我会得到不同的结果。有人告诉我这样写效率很低。我认为这是一种方便,我不认为效率低下。(顺便说一句,这行代码在一个递归调用的函数中)。
完整代码(转换为具有不同基数的数字系统)
import std.string;
string toBase(long n, int b)
in {
assert(2 <= b && b <= 35);
} body {
static string sign;
if (n < 0) {
n *= -1;
sign = "-";
}
enum chars = digits ~ uppercase;
size_t r = cast(size_t)(n % b);
if (n == r) {
return sign ~ chars[r];
}
return toBase((n - r) / b, b) ~ chars[r];
}编辑:更新代码,响应评论,与问题无关
string toBase(long n, int b)
in {
assert(2 <= b && b <= 35);
} body {
enum chars = digits ~ uppercase;
long r = n % b;
char c = chars[cast(size_t) abs(r)];
if (n == r) {
return (n < 0 ? "-" : "") ~ c;
}
return toBase((n - r) / b, b) ~ c;
}发布于 2011-07-03 21:05:47
像这样的enum实例化总是在编译时求值(当在编译时不可能求值时抛出编译错误)。
因此,连接是在编译时完成的,不可变版本存储在代码中并在运行时引用
发布于 2011-07-17 01:57:21
自己检查字符串是否在编译时连接的一种方法是编译代码并检查目标文件。假设您的文件名为test.d
dmd -c test.d
objdump test.o | grep -C3 "012345"...should产生类似如下的结果:
Contents of section .rodata:
0000 2d000000 00000000 00000000 00000000 -...............
0010 01000000 00000000 00000000 00000000 ................
0020 30313233 34353637 38394142 43444546 0123456789ABCDEF
0030 4748494a 4b4c4d4e 4f505152 53545556 GHIJKLMNOPQRSTUV
0040 5758595a 00000000 00000000 00000000 WXYZ............
0050 24000000 00000000 20000000 00000000 $....... .......(这是在Linux上;在其他平台上,您将需要不同的工具来检查目标文件。)
如果您将enum更改为const或string,您(很可能)将不会得到任何输出:将不会有grep要查找的连接字符串。
但是,即使不使用enum,编译器也可以在编译时连接字符串。考虑这个程序:
import std.stdio;
enum a = "Aaaa";
enum b = "Bbbb";
enum c = "Cccc";
void main()
{
enum x = a ~ b;
const y = b ~ a;
string z = a ~ c;
writeln(x, y, z);
}现在,编译它,并检查目标文件:
% dmd -c test2.d && objdump -s test2.o | egrep "(Aaaa|Bbbb)"
0000 42626262 41616161 00000000 00000000 BbbbAaaa........
0020 41616161 43636363 00000000 00000000 AaaaCccc........
0040 41616161 42626262 00000000 00000000 AaaaBbbb........我们可以看到x、y和z都是静态文字。(将a、b和c标记为const而不是enum,您可能会看到不同的行为。)因此,虽然enum是编译时求值的保证,但enum的缺失并不妨碍编译时求值。
https://stackoverflow.com/questions/6562860
复制相似问题