gpt4 book ai didi

c# - 是否可以在 C# 中进行内联以优化字符串连接?

转载 作者:行者123 更新时间:2023-11-30 21:46:02 26 4
gpt4 key购买 nike

假设您有这样的 C# 代码:

const string ABC = "ABC";
const string XYZ = "XYZ";

var result = ABC + ":" + XYZ;

此类代码由编译器优化,因此结果变量中有一个常量字符串文字“ABC:XYZ”,而不是在运行时实际连接 3 个字符串。

现在我想介绍一个辅助函数,它可以对用户隐藏连接(使代码更健壮,更不容易出错):

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
static string Combine(string first, string second) => first + ":" + second;

const string ABC = "ABC";
const string XYZ = "XYZ";

var result = Combine(ABC, XYZ);

在这种情况下,我看到该方法实际上内联在调用方法中,但在反汇编中我可以清楚地看到它调用了 string.Concat(string a, string b, string c) 在运行时,而不是只有一个常量字符串文字“ABC:XYZ”。

我知道在编译过程中速度和质量之间存在平衡,但是是否有任何技巧可以让 Combine 方法作为 C++ 宏来避免在运行时出现冗余字符串连接?

附言引入计算一次的静态只读字符串并不是问题的答案。

最佳答案

了解 MethodImplOptions.AggressiveInlining 提示及其含义/用途非常有用。

我的理解是,方法内联(无论它是否被程序员暗示/希望积极地完成)- 都是关于调用站点(即,在你的情况下,关于“由谁/where"你的 Combine 被称为),而不是关于什么否则构成了(可能内联的)方法的主体。

换句话说,当你重构你的表达式时

... ABC + ":" + XYZ ...

(这显然是常量折叠优化的“完美”/标称候选者)

进入

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static string Combine(string first, string second) => first + ":" + second

然后

(在调用站点)

... Combine(ABC, XYZ) ...

你真的“告诉”了编译器一些完全不同的东西:

“我想要一个接受两个字符串并返回第三个字符串的静态方法,我想在这个调用站点调用它,哦,请尝试为我内联它。”

因为在你的情况下,Combine 显然是一个纯非递归函数,它对调用堆栈不做任何事情,无论它是用实际参数(无论是否是那些常量)调用它都不能“就地”重写,它确实是内联它的调用是可行的——但这仍然没有说明还有什么其他的,额外的优化是可能的over Combine 方法的body 本身,这里等同于(在 lambda 脱糖之后)

return first + ":" + second;

(因此编译为

return string.Concat(first, second);

如你所见)

毕竟,如果代码的其他部分具有依赖于反射(通过 System.Reflection 的功能)的逻辑怎么办?它仍然需要在某处声明为成员并附加一个主体,不是吗? (同样,它是否可以“作为奖励”在这里或那里内联等)

从那里,“附在它上面的物体”意味着必须有一个,而且恰好是一个,用 CIL/MSIL 等表示。

这就是我如何看待您的 Combine 方法上的这个 [MethodImpl(MethodImplOptions.AggressiveInlining)] 只是一个提示,“嘿,拜托,让我们尽可能避免在这里和那里使用唯一、愚蠢的堆栈框架来调用 Combine。 “-- 仅此而已。

关于c# - 是否可以在 C# 中进行内联以优化字符串连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39581047/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com