私は単純なシナリオを持っています。ここでは、ストックオブジェクトのリストの式コンパイル済みツリーのパフォーマンスをテストしようとしています。以下はコードですコンパイルされた式ツリーのパフォーマンス
表現コンパイルツリーのパフォーマンスは、静的ラムダコールよりも5倍遅いです。これが表現されたコンパイルされたツリーで期待できる標準的なパフォーマンスかどうかはわかりません。どんな洞察にも感謝します。
LambdaExpression();
List<Stock> stocks = new List<Stock>();
for (int ctr = 0; ctr <= 5000000; ctr++)
{
Stock stk1 = new Stock() { Price = ctr, Symbol = "A", CloseDate = DateTime.Now, FaceValue = ctr } ;
stocks.Add(stk1);
}
CompileTimeLamda(a);
DynamicLambda(a);
public static void LambdaExpression()
{
ParameterExpression CS1 = Expression.Parameter(typeof(Stock), "d");
var line1 = Expression.Equal(Expression.Property(CS1, typeof(Stock).GetProperty("Symbol")), Expression.Constant("MSFT", typeof(string)));
var line2 = Expression.GreaterThan(Expression.Property(Expression.Property(CS1, typeof(Stock).GetProperty("CloseDate")),typeof(DateTime).GetProperty("Millisecond")),
Expression.Constant(0, typeof(int)));
var line3 = Expression.GreaterThan(Expression.Property(CS1, typeof(Stock).GetProperty("Price")), Expression.Constant((double)0, typeof(double)));
var line4 = Expression.And(line1,line2);
var line5 = Expression.OrElse(line4, line3);
func = Expression.Lambda<Func<Stock, bool>>(line5, new ParameterExpression[] { CS1 }).Compile();
}
public static void DynamicLambda(List<Stock> stks)
{
Stopwatch watch = new Stopwatch();
watch.Start();
foreach (var d in stks)
{
func(d);
}
watch.Stop();
Console.WriteLine("Dynamic Lambda :" + watch.ElapsedMilliseconds);
}
public static void CompileTimeLamda(List<Stock> stks)
{
Stopwatch watch = new Stopwatch();
watch.Start();
foreach (var d in stks)
{
if (d.Symbol == "MSFT" && d.CloseDate.Millisecond > 0 ||
(d.Price) > 0) ;
}
watch.Stop();
Console.WriteLine("Compile Time Lamda " +watch.ElapsedMilliseconds);
}
コンパイル済みのILを確認してください。オプティマイザがすべてのコードを強制終了している可能性があります。 – SLaks
2つのラムダ式を実際に比較していません。 2番目のコードはコンパイルされたコードです(つまり、代理人はいません)。デリゲートが遅くなっている可能性は非常に高いです。 – MikeKulls
あなたはリンゴとオレンジを比較しているようです。 "compile time lambda"はラムダをまったく使用しません。さらに、コンパイラは実際には何もしていないのでループを最適化しています(空のステートメント ";") –