2

更新しました

この問題は、XmlSerializer と逆シリアル化の問題ではなく、実際にはリモート ソースからの応答ストリームの読み取りに関する問題であると判断されました。Chris SinclairJesse C. Slicerに感謝し、私が見た不一致を判断する際に助けと指示を与えてくれました。


XmlSerializerXML データの静的ブロックをカスタム クラスに逆シリアル化するのにかかる時間をプロファイリングしてきましたがMyXmlObject、データがまったく同じであるにもかかわらず、要求ごとに時間が大幅に変動するようです。

XML がメソッドに渡された瞬間に逆シリアル化のタイミングを開始し、serializer.Deserialize()終了するとすぐにタイミングを停止します。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
//initialization stuff and writing to request stream.

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
    //If I run a stopwatch up to this point, I get the round trip time,
    //so I know that the stream has already been received at this point.

    using (Stream stream = response.GetResponseStream()) //In production this stream is received from a remote server.
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        MyXmlObject obj = (MyXmlObject)serializer.Deserialize(stream);

        stopwatch.Stop();
    }
}

私のXmlSerializerオブジェクトは次のように定義されています。

private static readonly XmlSerializer serializer = new XmlSerializer(typeof(MyXmlObject));

私の WCF Web サービスは、マルチスレッドのシングルトンです。

[ServiceBehavior(
    ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.Single)]

以下は、わずか 177,792 バイトの XML データの静的ブロックを逆シリアル化する 15 の同時要求に対して取得した結果です。

177,792 バイトの静的 XML ファイル

Request   Execution (ms)
1         300
2         302
3         303
4         303
5         368 *High
6         303
7         302
8         242 *Low
9         243
10        244
11        245
12        242
13        243
14        883 *Outlier
15        260

ご覧のとおり、ある程度一貫していますが、それでも約 +/-100ms 変動しています。

この比較的小さな XML ファイルでは、変動は最小限に抑えられますが、より大きなファイル (私の WCF Web サービスでより頻繁に受け取ることになる) をフィードすると、大幅に変動します。

3,851,199 バイトの静的 XML ファイル

Request   Execution (ms)
1         1384
2         2402
3         1715
4         4000 *Outlier
5         1310
6         2132
7         1388
8         1654
9         1183
10        1464
11        2368
12        2752 *High
13        1094 *Low
14        1838
15        1940

ご覧のとおり、XML ファイルの逆シリアル化にかかる時間は、小さいファイルの場合よりも大幅に変動しています。

比較的同じ (+/- 100 ミリ秒のみ) であると予想しますが、代わりに +/- 1200 ミリ秒以上の差が見られます。

さらに、2.5 秒は、XML を C# POD オブジェクトに逆シリアル化するために諦めたくないほどの時間です。興味深いのは、データをサーバーに返すときに、WCF が C# POD オブジェクトを比較的短時間で JSON にシリアル化することです。

質問

  • こうした変動はなぜ起こるのでしょうか。
  • これらの変動を最小限に抑えるにはどうすればよいでしょうか?
  • このサイズの着信 Xml を C# POD オブジェクトの階層に変換するのに、より高速な別のタイプの Xml デシリアライゼーションはありますか?
    • おそらくDataContractSerializer
    • ボンネットの下でDataContractSerializer使用しませんか?XmlSerializer

この問題を診断するのに役立つ、省略した必要な情報があれば教えてください。ありがとう。

4

2 に答える 2

2

あなたのコメントとベンチマークの方法を考えると、低速または変動の原因が XML デシリアライゼーションにあるとは思えません。

私の経験ではXmlSerializer、デシリアライゼーションに を使用すると非常に高速であり、確かに ~3.5 メガバイトのファイルで 2 ~ 4 秒の領域ではありません。ネットワーキングなしで静的な XML 文字列を単純に逆シリアル化する別のテストを行った場合、非常に高速であることがわかるでしょう (私は 50 ミリ秒未満を賭けますが、確かに 2000 ミリ秒には遠く及びません)。

ただし、投稿したコードでは、ネットワークの問題または時間に影響を与えるその他の要因があると思います。ベンチマーク テストを変更して、ストリームの読み取りを XML の逆シリアル化から分離すると、逆シリアル化自体が全体の時間にほとんど影響を与えないことがわかります。

ここでは、WCF サービスで他のネットワークの問題が発生していると思われます。XML デシリアライゼーションを完全に削除し、生データのストリームを読み取る速度を単純に測定する新しい質問を投稿することをお勧めします。ここではシリアライゼーションは問題ではないため、ユーザーはその側面を最適化/構成/改善する方法についてより良いアイデアを提供できるかもしれません。

于 2013-08-23T15:47:34.503 に答える