2016-09-19 7 views
2

を使用すると、C#のコードがあるとします。結果変数ではなく、3つの文字列の実際の連結をやって:あなたはリテラル1つの定数文字列「XYZ ABC」を持っているので、C#で文字列の連結を最適化するインライン化は可能ですか?

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

var result = ABC + ":" + XYZ; 

このようなコードは、コンパイラによって最適化されています実行時に

[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); 

を、私はこの方法が実際にインライン化されていることが分かり、この場合:

は、今私は(コードより堅牢かつ少ないエラーが発生しやすくするために)、ユーザからの連結を非表示になりますヘルパー関数を紹介したいと思います呼び出しメソッドでは、逆アセンブリでは、定数文字列リテラル "ABC:XYZ"の代わりに、実行時にstring.Concat(string a, string b, string c)を呼び出していることがはっきり分かります。

コンパイル時に速度と品質のバランスが取れていることを理解していますが、CombineメソッドをC++マクロとして動作させて実行時の冗長な文字列連結を回避する方法はありますか?

P.S.一度計算される静的な読み取り専用文字列を導入することは、その質問に対する答えではありません。

+0

なぜ、string.Concat()関数を使用できないのですか? – MethodMan

+0

それは遅いので、私はパフォーマンスが必要 –

+0

私の最後からのあなたの例に基づいてそれを実行しています..遅いではない..何のstring.Join()メソッドについて.. – MethodMan

答えて

3

MethodImplOptions.AggressiveInliningヒントと、それが何であるか/それが有用であることを理解することは有益です。

私の理解では、そのメソッドのインライン化(​​それはほのめかしていますか/積極的かを行うことにするプログラマが望んだ)である - つまり、あなたのケースでは、「誰が/ここで」あなたのすべてについて約呼び出しサイト( Combineが呼び出されます)、それ以外の場合(おそらくインライン化された)メソッドの本体を構成するものではありません。あなたは

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

に(明らかに、正確に一定折りたたみ最適化のための "完璧な" /名目候補である)あなたの表現

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

をリファクタリングつまり

、次に

(コールサイト)

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

あなたが本当にコンパイラとは全く別の何か「を語った」:

「私は2つの文字列を取り、第三を返す静的メソッドをしたい、私は、右ここでこの呼び出しサイトでそれを呼びたいですああ、私のためにインラインにしてみてください。"

あなたのケースでは、Combineは明らかに実際の引数で呼び出されている(定数であるかどうかにかかわらず)どこでも書き換えられない呼び出しスタックを何もしない純粋で非​​再帰的な関数です。確かにその呼び出しをインライン化することが可能である - それはまだ他、追加の最適化をするためにここに同等以上の組み合わせ方法の自体、可能何ができるかについては何も言いません

return first + ":" + second; 

((ラムダ脱糖後)したがって、

return string.Concat(first, second); 

お気づきのように)結局

、どのようなあなたのコードの他の部分は、その上に()するSystem.Reflectionの機能を通して反映さに依存ロジックを持っている場合は?それはまだどこかのメンバーとして宣言され、それに身体が付いている必要がありますか?

そこから「それに付随する身体」は、CILで表現されたものでなければならないことを意味していることを暗示しています(つまり、「ボーナス」としてインラインでインライン化できるかどうか)/MSILなど

これは、[MethodImpl(MethodImplOptions.AggressiveInlining)]がCombineメソッドの単なるヒントとして「ヘイ、お願いします。私たちができる限り、結合してください。 - それ以上に何もない。

+0

答えをありがとう。私はなぜそれがdownvotedのどちらかを理解していない - それは正当なコンパイラの最適化の質問StackOverflowのガイドラインに従って掲示される。私は、コンパイラに注入されたメソッドbodyを使って呼び出し元のボディを最適化するように強制することが可能であるかどうか不思議です。私は答えがノーだと思うが、ドットネットコンパイラの達人がこの質問に遭遇し、そのような前提を確認できることを願っている。 –

0

これはコンパイル時の織り方を使用して行うことができます。ここでのアイデアは、あなたのメソッドのすべての呼び出しサイトを見つけ出し(インライン化せずに)、コンパイル時にldtokenのオペコードをオペランドとして連結された文字列で置き換えます。

これらのツールは、目的を達成するのに役立ちます。

?PostSharp ?Aspect.NET。フェニックスに依存します。 ?AspectDNG。セシルに頼っています。 ?ComposeStar/StarLight ?グリッパーLoom.NET ?Phx.Morph/Wicca。フェニックスに依存します。

関連する問題