9

コンパクトなフレームワーク アプリケーションに取り組んでおり、パフォーマンスを向上させる必要があります。アプリは現在、オブジェクトを XML にシリアル化し、データベースに保存することでオフラインで動作します。プロファイリング ツールを使用すると、これがかなり大きなオーバーヘッドであり、アプリの速度が低下することがわかりました。バイナリシリアライゼーションに切り替えるとパフォーマンスが上がると思ったのですが、コンパクトなフレームワークではサポートされていないため、protobuf-net を調べました。シリアル化は高速に見えますが、逆シリアル化ははるかに遅く、アプリはシリアル化よりも多くの逆シリアル化を行っています。

バイナリのシリアル化を高速化する必要がありますか?そうであれば、パフォーマンスを高速化するために何ができますか? XML とバイナリの両方を使用する方法のスニペットを次に示します。

XML シリアル化:

public string Serialize(T obj)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream();
  XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
  serializer.Serialize(stream, obj);
  stream = (MemoryStream)writer.BaseStream;
  return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length));
}
public T Deserialize(string xml)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));            
  return (T)serializer.Deserialize(stream);
}

Protobuf-net バイナリ シリアル化:

public byte[] Serialize(T obj)
{
  byte[] raw;
  using (MemoryStream memoryStream = new MemoryStream())
  {
    Serializer.Serialize(memoryStream, obj);
    raw = memoryStream.ToArray();
  }

  return raw;            
}

public T Deserialize(byte[] serializedType)
{
  T obj;
  using (MemoryStream memoryStream = new MemoryStream(serializedType))
  {
    obj = Serializer.Deserialize<T>(memoryStream);
  }
  return obj;
}
4

6 に答える 6

6

Marc Gravall は、最初のイテレーションにはモデルを構築するオーバーヘッドがあると指摘したので、XML とバイナリの両方についてシリアライゼーションとデシリアライゼーションの平均 1000 回のイテレーションを取るいくつかのテストを行いました。最初に Compact Framework DLL の v2 を使用してテストし、次に v3.5 DLL を使用してテストを試みました。これが私が得たものです、時間はミリ秒です:

.NET 2.0
================================ XML ====== Binary ===
Serialization 1st Iteration      3236       5508
Deserialization 1st Iteration    1501       318
Serialization Average            9.826      5.525
Deserialization Average          5.525      0.771

.NET 3.5
================================ XML ====== Binary ===
Serialization 1st Iteration      3307       5598
Deserialization 1st Iteration    1386       200
Serialization Average            10.923     5.605
Deserialization Average          5.605      0.279
于 2009-07-08T12:56:18.667 に答える
3

メソッドの主な費用は、XmlSerializer クラスの実際の生成です。シリアライザーの作成は時間のかかるプロセスであり、オブジェクト タイプごとに 1 回だけ行う必要があります。シリアライザをキャッシュしてみて、パフォーマンスが向上するかどうかを確認してください。

このアドバイスに従って、アプリのパフォーマンスが大幅に向上し、XML シリアル化を引き続き使用できるようになりました。

お役に立てれば。

于 2011-11-19T17:58:32.423 に答える
1

興味深い...考え:

  • これはどのバージョンの CF ですか。2.0? 3.5? 特に、CF 3.5 にはDelegate.CreateDelegate、protobuf-net が CF 2.0 よりもはるかに高速にプロパティにアクセスできるようにする機能があります。
  • フィールドまたはプロパティに注釈を付けていますか? 繰り返しになりますが、CF ではリフレクションの最適化は制限されています。プロパティを使用すると、CF 3.5でパフォーマンスを向上させることができます。フィールドの場合、私が利用できる唯一のオプションはFieldInfo.SetValue

他にも CF には存在しないものがたくさんあるため、いくつかの場所で妥協する必要があります。非常に複雑なモデルの場合、CF のジェネリック制限に関する既知の問題もあります。修正が進行中ですが、これは大きな変更であり、「しばらく」かかります。

XmlSerializer情報については、さまざまな形式 (および protobuf-netを含む) を比較する通常の (完全な) .NET に関するいくつかのメトリックがここにあります

于 2009-07-07T12:34:33.473 に答える
0

オブジェクトのシリアル化、またはデータベースへの書き込みでパフォーマンスが低下しますか?それらを書き込むことは、ある種の遅いストレージにヒットする可能性が高いので、シリアル化ステップよりもはるかに大きなパフォーマンスヒットになると思います。

Marc Gravellによって投稿されたパフォーマンス測定は、1,000,000回の反復でパフォーマンスをテストしていることに注意してください。

それらをどのようなデータベースに保存していますか?オブジェクトはメモリ内でシリアル化されていますか、それともストレージに直接シリアル化されていますか?それらはどのようにデータベースに送信されますか?オブジェクトの大きさはどれくらいですか?1つが更新されたら、すべてのオブジェクトをデータベースに送信しますか、それとも変更されたオブジェクトだけを送信しますか?何かをメモリにキャッシュしていますか、それとも毎回ストレージから再読み込みしていますか?

于 2009-07-08T06:36:16.093 に答える
0

クラスのカスタム シリアル化クラスを作成してみましたか? 汎用シリアライザーである XmlSerializer を使用する代わりに (実行時に一連のクラスを作成します)。これを行うためのツールがあります (sgen)。ビルド プロセス中に実行すると、XmlSerializer のペースで使用できるカスタム アセンブリが生成されます。

Visual Studio を使用している場合、このオプションはプロジェクトのプロパティの [ビルド] タブで使用できます。

于 2009-07-07T12:41:54.990 に答える