2012-02-23 56 views
3

私はC#で書かれたWPFアプリケーションを持っています。何千ものオブジェクトをインスタンス化する必要があります。データベースサーバーからデータを取得した後、時間がかかる計算量の計算を実行する必要があります。プロセス全体には20〜30秒かかり、その80%は計算から来ています。WCFサービスオブジェクトの転送が遅い。それは普通ですか?

この問題の解決に役立つように、既に実行されたcalcで既にインスタンス化されたオブジェクトのコピーを保持し、要求に応じてインスタンス化されたオブジェクトを呼び出し元のクライアントに転送するWCFサービスを作成しました。

しかし、それは遅いです...本当に遅いです。元の方法よりもはるかに低速です。 WCFサービスからすべてのオブジェクトを転送するのに3〜4分かかるため、目的を破ってしまいます。

私は、サービスをバッファリングする代わりにストリーミングを試み、クライアントとサーバーの設定ファイルのさまざまなサービスオプションを増減しましたが、実際の設定にはまだ違いがありません。

この低速が予想されるのですか、それとも速くなければならず、いくつかのオプションを変更するだけですか?もしそうなら、どのようなオプションがありますか?

+0

これは、シリアライズに至る可能性があります。どのプロトコルエンドポイントを使用していますか?そして、どのようにオブジェクトが「大きく」なっていますか? –

+0

私はBasicHTTPBindingを使用します。オブジェクトは[Serializable]属性でシリアル化されます。すべてのオブジェクトの合計サイズは約350 MBです。 – Nullqwerty

+2

WCFでの私のお勧めは、電線で必要なデータだけを渡すことです。このため、私はしばしば、WCFに出入りするデータを可能な限り小さく保つために生データを含む 'DTO'または' POCO'オブジェクトで作業します。WCFはアイテムをローカルで実行するよりも処理速度が遅くなります。なぜなら、サーバーに移動してデータを取得するだけでなく、メモリからデータを取得する必要があるからです。実行している計算の種類は、計算結果をオブジェクト自体に保存できないだけですか? – Rachel

答えて

1

WCFは必ずしも遅いわけではありませんが、アプリケーションが正しく設計されていないと、アプリケーションが遅くなる可能性があります。それは、スポーツカーに数千ポンドの重さを積み込むことと比べることができます。車ですが、実際には適切に使用されていません。

まず、ワイヤで送信されるデータの量を最小限に抑える必要があると思います(詳細は後で説明します)。一旦ワイヤーに接続すると、HTTPの代わりにTCPまたは名前付きパイプを使用すると、パフォーマンスが大幅に向上します。 Choosing a Transportを参照してください。ほとんどのネットワークは簡単に使えるように設定されているためHTTPは簡単ですが、大規模なデータセット用には設計されていません。

遅延が計算から生じる場合、WCFサービスが達成できるのは、処理をサーバーからクライアントにオフロードすることだけです。結局のところ、これはサーバーへの同時要求が大量であることを計画しているが、気づいたことがあれば、エンドユーザーの時間が短くなるわけではありません。あなたが行うことに集中すべきは、計算時間を最小限に抑えることです。

何が照会されているのか、何が返されているのか、そして計算が何をしているのかを明らかにしていないので、特定のものを与えるのは難しいです。しかし、Visual Studio SQL Server Projectsを経由して、アプリケーションサーバーからデータベースサーバーにコードをオフロードすることで、大きなデータセットで大きな結果が得られました。 .NETとMSSQLはどちらもCLRに記述されているので、ネイティブデータベースオブジェクト(user defined functionsなど)をC#またはVBまたは他のCLR言語で記述し、それらをデータベースに直接デプロイすることができます。その後、これらの関数をクエリで使用することができ、は非常にです。これらはネイティブSQLにコンパイルされているため高速です。私は、アプリケーション内でC#を実行しているときとデータベース内の同じ関数を実行しているときとの違いが大きかった。

+0

ありがとう!私はCLRルートに行くことを検討していました。私のアプローチでは、計算が既に実行されているということです。したがって、サーバが計算を実行するのに20分かかる場合でも、すでに完了しており、サービスがオブジェクトをキャッシュしているため、問題はありません。だから、クライアントが「私にオブジェクトを渡す」と言うと、サーバはすでに完了しているので、それらを再インスタンス化したり、calcを再実行する必要はありません。代わりに、サーバーは「確かに、ここにいる」と言うだけです。残念ながら、それはそれが言うために約5分かかりました。私はTCPまたは名前付きパイプルートを試すことができますが、私はそれをより速く発注する必要があります。そうだろうか?どうも! – Nullqwerty

+1

申し訳ありませんが、私は、TCP /名前付きパイプのオーダーが速くなるかどうかは確信できません。クライアントは本当に一度にすべての情報を必要としますか、それとも徐々に情報をロードできますか? (ページングや "無限スクロール"などで) – Jeff

+0

私はそれをどう扱うかについてさまざまな選択肢があります。これは、再設計の最小量を必要とし、現在の設計と最もうまく適合しました。しかし、間違いなく他の選択肢があります。ちょうどこのスピードの問題が、設定を変更することで簡単に解決できるものではないことを確認したかったのです。私はtcp /名前付きパイプルートをチェックアウトします。助けてくれてありがとう – Nullqwerty

1

あなたのアプリケーションの仕事の80%が計算から来た場合、それは例えばTask Parallel Libraryなどのいくつかの部分をパラレル化するのがよいでしょう。

+0

ありがとう!うん、私は先週できるPLinqを実装した。これはスピードの大幅な改善だった。しかし、ヒントをありがとう! – Nullqwerty

関連する問題