12

EntityFrameworkを利用したMVC3サイトに対してmvc-mini-profilerを設定しました。すべてが適切に構成されています。Application_Startでプロファイリングを開始し、Application_Endで終了します。プロファイリング部分は問題なく機能します。

ただし、データモデルオブジェクトの生成をプロファイラ可能なバージョンの提供に交換しようとすると、パフォーマンスが低下します。すべてのSQLクエリではありませんが、一部のクエリではページ全体の読み込みに約5倍の時間がかかります。(IIS Expressを起動した後の最初のページの読み込みには少し時間がかかりますが、これは持続します。)

SQLのクエリ、実行、および「データ読み取り」に費やされる時間はごくわずかです(〜2msトップ)。

var person = dataContext.People.FirstOrDefault(p => p.PersonID == id);

...ラップされた場合、using(profiler.Step())300〜400ミリ秒かかると記録されます。dotTraceを使用してプロファイルを作成しました。これにより、実際には通常どおりEFで時間が費やされていることが確認されました(プロファイラ可能なコンポーネントは非常に短時間で表示されます)が、時間がかかるだけです。

これにより、接続またはその構成部分の一部に十分なデータが欠落しており、EFのパフォーマンスが大幅に低下していると私は信じています。

これは、コンテキストオブジェクトを作成するために使用しているものです(私のedmxモデルのクラスはDataContextと呼ばれます)。

var conn = ProfiledDbConnection.Get(
    /* returns an SqlConnection */CreateConnection());
return CreateObjectContext<DataContext>(conn);

私はもともとmvc-mini-profilerが提供ObjectContextUtils.CreateObjectContextするメソッドを使用していました。私はそれに飛び込んで、ワイルドカードメタデータワークスペースのパス文字列を設定していることに気づきました。コードを使用する他のプロジェクトと同様に、データベースレイヤーを1つのプロジェクトと複数のMVCサイトに分離しているため、これらのパスが変更されており、より具体的にしたいと思います。また、これがパフォーマンスの問題の原因だと思いました。CreateObjectContextこれを提供するために、機能を自分のプロジェクトに複製しました。

    public static T CreateObjectContext<T>(DbConnection connection) where T : System.Data.Objects.ObjectContext {
        var workspace = new System.Data.Metadata.Edm.MetadataWorkspace(
          GetMetadataPathsString().Split('|'),
          // ^-- returns 
          //  "res://*/Redacted.csdl|res://*/Redacted.ssdl|res://*/Redacted.msl"
          new Assembly[] { typeof(T).Assembly });

        // The remainder of the method is copied straight from the original,
        // and I carried over a duplicate CtorCache too to make this work.
        var factory = DbProviderServices.GetProviderFactory(connection);
        var itemCollection = workspace.GetItemCollection(System.Data.Metadata.Edm.DataSpace.SSpace);
        itemCollection.GetType().GetField("_providerFactory", // <==== big fat ugly hack
            BindingFlags.NonPublic | BindingFlags.Instance).SetValue(itemCollection, factory);
        var ec = new System.Data.EntityClient.EntityConnection(workspace, connection);
        return CtorCache<T, System.Data.EntityClient.EntityConnection>.Ctor(ec);
    }

...しかし、それはあまり違いがないようです。メタデータワークスペースパスでより具体的な上記のハッキングされたバージョンを使用するか、mvc-mini-profilerが提供するバージョンを使用するかにかかわらず、問題は依然として存在します。私もこれを試したことがあると言っておきたいと思いました。

これらすべてを使い果たしたので、私は私の知恵の終わりにいます。繰り返しになりますが、いつものようにデータコンテキストを提供するだけで、パフォーマンスが低下することはありません。「プロファイラブル」なデータコンテキストを提供すると、特定のクエリのパフォーマンスが急落します(これに何が影響するかはわかりません)。mvc-mini-profilerは何が間違っているのでしょうか?私はまだそれに間違ったデータを供給していますか?

これはこの人が遭遇したのと同じ問題だと思います。

4

2 に答える 2

5

今日、この問題を解決しました。

参照:http ://code.google.com/p/mvc-mini-profiler/issues/detail?id = 43

それは、私たちの派手なハックのいくつかが十分にキャッシュされなかったために起こりました。特に:

var workspace = new System.Data.Metadata.Edm.MetadataWorkspace(
     new string[] { "res://*/" },       
     new Assembly[] { typeof(T).Assembly });

非常にコストのかかる呼び出しであるため、ワークスペースをキャッシュする必要があります。

于 2011-07-25T10:36:28.060 に答える
-2

定義上、プロファイリングは、プロファイリングされるアプリケーションのパフォーマンスに影響を与えます。プロファイラーは、アプリケーション全体に独自のメソッド呼び出しを挿入し、低レベルのシステムコールをインターセプトし、そのすべてのデータをどこかに記録する必要があります(ディスクへの書き込みを意味します)。これらのタスクはすべて、貴重なCPUサイクル、メモリ、およびディスクアクセスを消費します。

于 2011-06-27T17:15:50.447 に答える