c# - 如何在不进行系统调用的情况下获得恒定的字符串长度?

标签 c# optimization cil

示例代码:

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) enter image description here

现在:为什么有一个系统调用而不是简单的 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/

相关文章:

c# - 如何在 C# 中打印 itf 条形码

c++ - 在 Linux 上将文件写入磁盘的最快方法

.net - 为什么在 Visual Studio 2010 中安装了 F# 运行时?

c# - 跳过对没有 DynamicMethod 的动态生成方法的可见性检查

optimization - 英特尔汇编程序优化

.net - 发出IL以调用Math函数

c# - 如何在 C# 中检索所有 cookie?

c# - FileHelpers:混合分隔和固定长度记录

c# - 无法在 VS Code 终端中创建 C# 控制台应用程序

php - MySQL 连接 "Cost"?