我能以某种方式提示编译器在 C# 中为我计算常量表达式吗?
Can I somehow hint the compiler to calculate constant expression for me in C#?
我这里有以下struct
:
struct Time
{
public uint SEC;
public uint MIN;
public uint HOUR;
public uint DAY;
}
现在我要计算整个秒数:
static uint F(Time t)
{
uint r = 0;
r += t.DAY * 24 * 60 * 60;
r += t.HOUR * 60 * 60;
r += t.MIN * 60;
r += t.SEC;
return r;
}
这里的问题是 C#
为我生成了以下 ASM
:
Program.F(Time)
L0000: mov eax, [rcx+0xc]
L0003: lea eax, [rax+rax*2]
L0006: shl eax, 3
L0009: imul eax, 0x3c ; it literally multiples one by one,
L000c: imul eax, 0x3c ; although they are int literals.
L000f: imul edx, [rcx+8], 0x3c
L0013: imul edx, 0x3c
L0016: add eax, edx
L0018: imul edx, [rcx+4], 0x3c
L001c: add eax, edx
L001e: add eax, [rcx]
L0020: ret
现在,当我像这样手动计算它们时:
static uint G(Time t)
{
uint r = 0;
r += t.DAY * 86400;
r += t.HOUR * 3600;
r += t.MIN * 60;
r += t.SEC;
return r;
}
然后它生成了我正在寻找的结果:
Program.G(Time)
L0000: imul eax, [rcx+0xc], 0x15180
L0007: imul edx, [rcx+8], 0xe10
L000e: add eax, edx
L0010: imul edx, [rcx+4], 0x3c
L0014: add eax, edx
L0016: add eax, [rcx]
L0018: ret
如您所见,它删除了多个 IMUL
(很明显)。这是我正在寻找的 ASM
输出。
问题
- 我能以某种方式提示
C#
编译器为我计算整数文字吗?我想像第一个例子一样保留它,因为它对我来说更干净。这些示例(函数 F
和 G
)是否有所不同,或者为什么 C#
编译器决定不计算它们?
备注
- 这里是SharpLablink.
如果将常量括在括号中,编译器将简化表达式。
static uint F(Time t)
{
uint r = 0;
r += t.DAY * (24 * 60 * 60);
r += t.HOUR * (60 * 60);
r += t.MIN * 60;
r += t.SEC;
return r;
}
我这里有以下struct
:
struct Time
{
public uint SEC;
public uint MIN;
public uint HOUR;
public uint DAY;
}
现在我要计算整个秒数:
static uint F(Time t)
{
uint r = 0;
r += t.DAY * 24 * 60 * 60;
r += t.HOUR * 60 * 60;
r += t.MIN * 60;
r += t.SEC;
return r;
}
这里的问题是 C#
为我生成了以下 ASM
:
Program.F(Time)
L0000: mov eax, [rcx+0xc]
L0003: lea eax, [rax+rax*2]
L0006: shl eax, 3
L0009: imul eax, 0x3c ; it literally multiples one by one,
L000c: imul eax, 0x3c ; although they are int literals.
L000f: imul edx, [rcx+8], 0x3c
L0013: imul edx, 0x3c
L0016: add eax, edx
L0018: imul edx, [rcx+4], 0x3c
L001c: add eax, edx
L001e: add eax, [rcx]
L0020: ret
现在,当我像这样手动计算它们时:
static uint G(Time t)
{
uint r = 0;
r += t.DAY * 86400;
r += t.HOUR * 3600;
r += t.MIN * 60;
r += t.SEC;
return r;
}
然后它生成了我正在寻找的结果:
Program.G(Time)
L0000: imul eax, [rcx+0xc], 0x15180
L0007: imul edx, [rcx+8], 0xe10
L000e: add eax, edx
L0010: imul edx, [rcx+4], 0x3c
L0014: add eax, edx
L0016: add eax, [rcx]
L0018: ret
如您所见,它删除了多个 IMUL
(很明显)。这是我正在寻找的 ASM
输出。
问题
- 我能以某种方式提示
C#
编译器为我计算整数文字吗?我想像第一个例子一样保留它,因为它对我来说更干净。这些示例(函数F
和G
)是否有所不同,或者为什么C#
编译器决定不计算它们?
备注
- 这里是SharpLablink.
如果将常量括在括号中,编译器将简化表达式。
static uint F(Time t)
{
uint r = 0;
r += t.DAY * (24 * 60 * 60);
r += t.HOUR * (60 * 60);
r += t.MIN * 60;
r += t.SEC;
return r;
}