示例代码:
const string UtcTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
public byte[] UtcTimeAscii => Encoding.ASCII.GetBytes(DateTime.UtcNow.ToString(UtcTimeFormat));
这是我得到的 Length
属性的 IL:(使用 Microscope
VS add in)
现在:为什么有一个系统调用而不是简单的 24
?
它是一个常量字符串。有没有办法提前告诉编译器它是已知的?
我知道,我可以将 24
定义为 const int
,但这是不对的,因为实际字符串与其长度之间没有直接绑定(bind)。当然我可以调用 Length()
但我只是好奇,也许有一种特殊的语法可以使用这种优化?
我也将配置从 Debug
切换到 Release
但系统调用仍然存在。
最佳答案
如果可以完成该优化,则不会由 C# 编译器完成,而是由 JIT 编译器在(嗯,就在之前)运行时完成。 IL 通常不指示正在发生的优化,并且永远不能证明没有给定的优化。
让我们看看实际运行的最终机器代码。你可以在调试器中这样做,如果你关闭“禁用模块加载优化”(否则你会看到故意未优化的机器代码),或者你可以使用sharplab.io:like this
C.M()
L0000: mov eax, 0x18
L0005: ret
结果很清楚:获取常量字符串的长度被优化为常量长度,不涉及调用甚至加载。顺便说一句,在任何情况下它都不是系统调用,它可能是对子程序的正常调用。
关于c# - 如何在不进行系统调用的情况下获得恒定的字符串长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69628189/