0

アプリケーションのプロファイリングを行っていると、タイプされた Upadte<> (および Query<>) ビルダーが要求ごとにラムダ式を評価し、多くの CPU を消費する不快な事実を発見しました。次のように、適切で最新の型の UpdateBuilder<> から切り替えると、 CPU の数パーセントが得られます。

var u = Update<MyPerson>.Inc(e => e.Age, Age);

古き良き静的文字列へ:

var u = Update.Inc("Age", Age);

QueryBuilder<> にも同じ問題があり、リクエストごとに式を評価し、貴重な CPU リソースを無駄に浪費します。

公式の LINQ ドライバーのページには次のように記載されています。

いずれにせよ、C# コンパイラは、クエリ構文を使用して記述されたすべてのクエリを内部でラムダ構文に変換するため、どちらのスタイルを選択してもパフォーマンス上の利点やペナルティはありません。

はい、 2 つの LINQ 構文のいずれかを選択した場合は当てはまります。しかし、LINQ 構文を使用する場合と使用しない場合では、パフォーマンスに大きな違いがあります。オーバーヘッドは、クライアントがクエリを実行する頻度によって異なります。私の場合、30%以上の差です!

素敵な型付き構文とパフォーマンスの両方を一緒に得る方法はありますか?

ビルダーの結果の単純なキャッシュは、各リクエストに動的パラメーターを渡す必要があることが明らかな限り、答えにはなりません。CPU コストのかかる部分 (ラムダ式の評価に関して) を「プリコンパイル」する方法を見つける必要がありますが、動的パラメーター (配列インデックスなど) は保持します。

4

1 に答える 1

0

あなたが引用した段落:

いずれにせよ、C# コンパイラは、クエリ構文を使用して記述されたすべてのクエリを内部でラムダ構文に変換するため、どちらのスタイルを選択してもパフォーマンス上の利点やペナルティはありません。

LINQ クエリの記述に使用できる 2 つの構文を参照します。

var query =
    from e in collection.AsQueryable<Employee>()
    where e.FirstName == "John"
    select e;

また

var query =
    collection.AsQueryable<Employee>()
    .Where(e => e.FirstName == "John");

一般に、LINQ クエリにオーバーヘッドがないことを意味するものではありません。すべての LINQ クエリは、実行時に同等の MongoDB クエリに変換する必要があり、そのプロセスには一定の CPU 時間が必要です。

将来的には可能であればそのオーバーヘッドを削減したいと考えていますが、このオーバーヘッドはクライアントでのみ発生し、サーバーには影響しないことに注意してください。

于 2013-05-09T20:26:20.383 に答える