2016-09-19 44 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。依靠鳳凰。