2016-09-19 28 views
2

假设有这样的C#代码:是否可以在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++宏来避免运行时多余的字符串连接?

P.S.引入一次得到计算的静态只读字符串不是问题的答案。

+0

为什么你不能只使用string.Concat()函数。? – MethodMan

+0

因为它很慢,我需要性能 –

+0

运行它根据你的例子从我的结尾是不是慢在wll ..怎么样string.Join()方法然后.. – MethodMan

回答

3

了解MethodImplOptions.AggressiveInlining提示以及它的用途/用途有用。

我的理解是,方法内联(无论是暗示/要积极或没有做程序员希望) - 是所有关于调用点(即,你的情况,关于“由谁/在”你的组合被称为),但不涉及构成(可能内联)方法的主体的内容。

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

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

(这正是 “完美”/标称为常量折叠优化候选人,很明显)

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

然后

(在呼叫地点)

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

你真的“告知”东西编译器完全不同:

“我想这需要两个字符串并返回第三静态方法,我想在此调用点就在这里调用它,哦,请尝试为我内联。“

因为在你的情况下,Combine显然是一个纯粹的非递归函数,它不会对调用堆栈做任何事情,在实际参数调用时(无论是否是常量),它不能被重写为”就地“的确是内联的调用是可行的 - 但仍然只字未提什么其他的,额外的优化可能是可能 Combine方法的身体本身,这里相当于

return first + ":" + second; 

((拉姆达脱糖后)并编为

return string.Concat(first, second); 

,你注意到)

毕竟,如果你的代码的其他部分在它有一个依赖于反映逻辑(通的System.Reflection的功能)?它仍然需要被宣布为某个地方的成员并且有一个附属于它的身体,不是吗? (再次,是否可以,“作为奖励”,在这里或那里内联等)

从那里,“一个附属于它的身体”意味着必须有一个,并且恰好一个,用CIL表示/ MSIL等

这就是我在你的Combine方法中看到这个[MethodImpl(MethodImplOptions.AggressiveInlining)]作为纯粹的提示,“嘿,请,让我们避免在这里和那里的唯一,愚蠢的堆栈帧调用结合,只要我们可以。“ - 除此之外没有任何东西。

+0

感谢您的回答。我不明白为什么它是downvoted - 这是一个合法的编译器优化问题发布根据StackOverflow指南。我只是好奇,如果有可能强制编译器优化调用者的身体与注入方法(ies)。我假设答案是否定的,但希望网络编译器的大师能够遇到这个问题,并且可以证实这种假设。 –

0

使用编译时编织可以做到这一点。这里的想法是,你会找到你的方法的所有调用网站(不要内联它们!),并在编译时用连接字符串作为操作数的ldtoken操作码替换它们。

这些工具将有助于实现您的目标。

•PostSharp •Aspect.NET。依靠凤凰。 •AspectDNG。依靠塞西尔。 •ComposeStar/StarLight •抓手织机.NET •Phx.Morph/Wicca。依靠凤凰。

相关问题