2017-11-13 4 views
4

Expressionツリーはimmutableなので、なぜコンパイラは文字列リテラルのような静的な表現に対して同じオブジェクト参照を使用しませんでしたか?質問を明確にするコンパイラが静的な式ツリーに対して同じオブジェクト参照を使用しなかったのはなぜですか?

例を参照してください:私は式の木を知っているよう

static void Main(string[] args) 
{ 
    Test(p => true);//2637164 
    Test(p => true);//3888474 
    Test("true");//-292522067 
    Test("true");//-292522067 
    Console.ReadKey(); 
} 

public static void Test(Expression<Func<string,bool>> exp) 
{ 
    Console.WriteLine(exp.GetHashCode()); 
} 

public static void Test(string str) 
{ 
    Console.WriteLine(str.GetHashCode()); 
} 
+0

重複した式を検出するより重複した文字列値を検出する方が簡単です。それを超えて、「なぜコンパイラはXをしないのですか?一般にスタックオーバーフローには役立ちません。それは_practical_programming_problem_ではなく、あなたが得る可能性のある唯一の答えは、推測になるだろう。いくつかの奇跡によって、コンパイラのその機能の作者が答えた場合、答えは、コンパイラにない他のすべての機能についても、ほぼ確実に同じことになるでしょう: "利益はコストを正当化するものではありません。 –

+1

@PeterDuniho:まあ、それは奇跡ではありません。それは私の特徴の一つでした。仕様によれば、コンパイラは許可されていますが、同一のラムダ参照を同じにする必要はありません。あなたが推測したように、その機能にはコストがかかり、コンパイラチームは、(1)決して起こらない状況に対して「最適化」を書くよりも良いことがあります。(2)開発者が望むならば。 –

+0

文字列リテラルは、コンパイラではなく、ランタイムによってインターンされます。 –

答えて

8

をコンパイラが文字列リテラルのように、静的な表現のために同じオブジェクト参照を使用していませんでしたなぜ不変のですか?

仕様では、コンパイラは許可されていますが、同一のラムダをインターンする必要はありません。

文字列リテラルは、ランタイムによって無料で使用できます。コンパイラ開発者にはコストがかかりません。

私がインターン表現木をしなかったのは、Visual Studioがスケジュールをずらしてしまったという事実が、貴重なリソースを実際には保存しない非現実的なシナリオに対して無用な "最適化"我々はその時間を実際にの最適化に費やしました。

0

あなたの実際の問題が何であるかを盲目的に推測します。参照の等価性の代わりに、this questionの答えを辞書のIEqualityComparerとして使用します。明らかにObject.ReferenceEqualsほど高速ではありませんが、私が想像する式ツリーをコンパイルするよりもはるかに高速です。

+0

私はこのアプローチを使用しますが、正確ではありません。辞書のキーがExpressionであれば、 GCはタルトをクリーニングできません。だから、Expressionを文字列と1対1に変換するユニークなHashCodeメソッドを使用します。 –

+0

どのようにして定数のtostringを行うのですか?特に直列化可能なオブジェクトではない? – MBoros

+0

私の場合、式はプロパティ記述子だったので、式を取得してエンティティのフルネームとプロパティ名に変換します。 –

関連する問題