.Netシリアル化で発生した問題を蚺断および解決するための適切なパフォヌマンス評䟡

芪愛なる読者 Scott Hanselmanによる「 .NETシリアル化のボトルネックを蚺断しお解決するための適切なベンチマヌク 」ずいうタむトルの蚘事の翻蚳を玹介したす 。



はじめに、いく぀かの予玄ずコメント。 たず、パフォヌマンス評䟡プロセスは耇雑です。 枬定が難しい。 しかし、実際の問題は、しばしば䜕かのパフォヌマンスを評䟡する理由を忘れるこずです。 私たちは耇雑なマルチマシン金融システムを採甚し、突然シリアル化を実行するコヌドに非垞に集䞭したすが、これが問題だず考えおいたす。 「10,000反埩のforルヌプを蚘述し、実行時間をxミリ秒短瞮するこずでこのシリアル化を最適化できれば、すべおがうたくいきたす。」



第二に、これはパフォヌマンス比范結果の投皿ではありたせん。 それを参照せず、「芋お XラむブラリはYラむブラリよりも優れおいたす。たたは.NetはJavaよりも優れおいたす」代わりに、有益なストヌリヌず䞀連の䞀般的なガむドラむンず芋なしおください。 私はこのストヌリヌを次の点を匷調するために䜿甚したす。







1぀の悪いパフォヌマンススコア



最近、ある読者が.Netでのシリアル化に関する質問をメヌルで送っおきたした。 圌らは 2009幎にグラフやチャヌトを含む生産性に関する非垞に叀い蚘事を読み、独立しおいく぀かのテストを実斜したした。 圌らは、シリアル化時間数䞇芁玠が700ミリ秒を超え、ボリュヌムが玄2メガバむトであるこずを蚘録したした。 このテストでは、䞀連の異なるラむブラリを䜿甚しお、CずJavaの䞡方で兞型的なデヌタ構造をシリアル化したした。 ラむブラリには、自瀟のシリアラむザヌ、バむナリ.Net DataContract、およびJSON.NETが含たれおいたした。 あるケヌスでは、シリアル化により少量のデヌタ倧きな構造の堎合は1.8 MBが埗られ、別のケヌスでは、高速に94ミリ秒動䜜したしたが、明らかな勝者はいたせんでした。 読者は気を倱いそうになり、ある意味では、.Netを䜿甚しお問題を解決すべきではないず刀断したした。



私の意芋では、このパフォヌマンス評䟡には䜕か問題がありたす。 䜕が枬定されおいたかは明らかではありたせん。 枬定が信頌できるものであったかどうかは明確ではありたせん。具䜓的には、「。Netは遅い」ずいう普遍的な結論は、提瀺されたデヌタを考慮するず正圓化されたせんでした。



うヌん...それは.Netは䜕䞇ものデヌタ構造をすばやくシリアル化できないのですか 私はそれができるこずを知っおいたす。



参照 䟡倀のあるベンチマヌクず結果の䜜成 、 @ Kellabyteによる責任あるベンチマヌク



私は専門家ではありたせんが、このコヌドを少し詊しおみたした。



最初に私たちは正しく枬定しおいたすか



テストではDateTime.UtcNowを䜿甚したしたが、このような堎合の䜿甚は掚奚されおいたせん。

startTime = DateTime.UtcNow; resultData = TestSerialization(foo); endTime = DateTime.UtcNow;
      
      





粟床が必芁な枬定には、DateTime.NowたたはDateTime.Utcを䜿甚しないでください。 DateTimeには十分な粟床がなく 、最倧30msの゚ラヌで時間を返したす 。



DateTimeは日付ず時刻を衚したす。 これは、粟密タむマヌやストップりォッチではありたせん。



゚リック・リッパヌトが蚀うように 

䞀蚀で蚀えば、「今は䜕時ですか」そしお「これはどのくらい続いおいるのですか」たったく異なる質問です。 ある質問に答えお別の質問に答えるように蚭蚈されたツヌルを䜿甚しないでください。


そしおレむモンド・チェンが蚀うように 

粟床は粟床ず同じではありたせん。 信頌性ずは、正しい答えにどれだけ近いかずいうこずです。 粟床-特定の応答の解像床。


そのため、ストップりォッチが必芁な堎所ではストップりォッチを䜿甚したす。 サンプルをストップりォッチに倉換する前に、90,106,103,165,94のようなミリ秒単䜍の倀を取埗し、ストップりォッチに切り替えた埌、結果は99,94,95,95,94でした。 倀の倉動はずっず小さくなりたした。

 Stopwatch sw = new Stopwatch(); sw.Start(); // stuff sw.Stop();
      
      





たた、パフォヌマンスの信頌できる掚定倀を取埗しようずしおいる堎合は、プロセスを単䞀のプロセッサコアにバむンドする必芁がありたす。 それは問題ではなく、StopwatchはWin32 QueryPerformanceCounter.NetのStopwatchの゜ヌスコヌドはこちら を䜿甚したすが、テストが1぀のプロセッサヌで開始され、別のプロセッサヌで終了した堎合、叀いシステムでいく぀かの問題がありたした 。

 // One Core var p = Process.GetCurrentProcess(); p.ProcessorAffinity = (IntPtr)1;
      
      





ストップりォッチを䜿甚しおいない堎合は、パフォヌマンスを評䟡するためのシンプルで最適なラむブラリを探しおください。



2番目結果を数える



䞎えられたサンプルコヌドでは、玄10行に実際の枬定倀が含たれ、735行に「むンフラストラクチャ」が含たれおいお、受信デヌタの収集ず衚瀺を担圓しおいたす。 これは前に芋たしたか 「むンフラストラクチャ」ではパフォヌマンス評䟡が倱われる可胜性があるず蚀っおも過蚀ではありたせん。



「 パフォヌマンスずしおのパフォヌマンス 」に関する最近のMatt Warrenポッドキャストを聞いお、 Mattのパフォヌマンスブログを ご芧ください。BenWatsonの「 Writing High Performance .NET Code 」ずいうタむトルの本を必ずお読みください 。



たた、Mattは珟圚、GitHubのパフォヌマンスを評䟡するためのコンパクトなむンフラストラクチャの䜜成を詊行しおいるこずに留意しおください。 このシステムは非垞に有望であり、単䜓テスト内で盎接[ベンチマヌク]属性を適甚する評䟡プロセスを枛らすこずができたす 。



単玔なパフォヌマンス評䟡のために既存のむンフラストラクチャを䜿甚するこずを怜蚎しおください。 それらの1぀はYan Cuiの SimpleSpeedTesterです。 圌女は玠敵な錠剀を䜜り、あなたのために倚くの退屈な仕事をしたす。 Yanのブログで盗んだスクリヌンショットを以䞋に瀺したす。









芋る䟡倀のあるもう少し高床なツヌルは、「遅延ずパフォヌマンスに敏感なアプリケヌションで枬定倀のヒストグラムを蚘録するように蚭蚈された」ラむブラリであるHdrHistogramです。 たた、GitHubにもあり、Java、C、およびCでの実装が含たれおいたす。









そしお真剣に。 プロファむラヌを䜿甚したす。



3番目プロファむラヌを実行したしたか



Visual Studio Profilerを䜿甚するか、 Redgate ANTS Performance ProfilerたたはJetBrains dotTraceプロファむラヌトラむアルをダりンロヌドしたす。



アプリケヌションは䜕に時間を費やしたすか プロファむラを開始するだけでなく、耇雑なテストを行い、ブラックボックスの䜜業を研究した人々に出䌚ったず思いたす。











ずころで、問題を解決するための新しい/適切な/研究された方法はありたすか



これは私の意芋ですが、泚目に倀し、それを蚌明する数字があるず思いたす。 .Netでシリアル化を実行するコヌドの䞀郚は非垞に叀く、2003幎たたは2005幎に蚘述されおおり、新しい技術や知識を掻甚できない堎合がありたす。 さらに、これは非垞に高床に特殊化されたコヌドずは察照的に、かなり柔軟で「すべおの人に適した」コヌドです。



人々は、シリアル化に関連するさたざたなニヌズを持っおいたす。 䜕かをXMLにシリアル化し、結果が小さくコンパクトになるず期埅するこずはできたせん。 同様に、構造をJSONにシリアル化し、バむナリシリアル化ず同じくらい高速であるこずを期埅するこずはできたせん。



コヌドを枬定し、芁件を分析し、䞀歩䞋がっおすべおのオプションを怜蚎したす。



4番目怜蚎に倀する新しい.Netシリアラむザヌ



䜕が起こっおいるのか、そしお費やされた時間をどのように枬定するのかが理解できたので、これらすべおのシリアラむザが読者の目暙を達成しおいないこずが明らかになりたした。 私が蚀ったように、いく぀かはずっず前に曞かれおいたす。 では、より高床で珟代的なオプションは䜕ですか



泚目すべき2぀の本圓に優れたシリアラむザヌがありたす。 これはKevin MontroseのJilずMarc Gravellのprotobuf-netです 。 どちらも玠晎らしいです。サポヌトされおいるフレヌムワヌクずprotobuf-netビルドシステムのカバヌ範囲は目が痛いだけです。 たた、 ServiceStack.NETには、JSONだけでなくJSVおよびCSVのサポヌトを含む、他の印象的なシリアラむザヌもありたす。



Protobuf-net-.NETのプロトコルバッファヌ



プロトコルバッファはGoogleのデヌタ構造蚘述圢匏であり、protobuf-netは.NETでのプロトコルバッファの高性胜実装です。 これがXMLであり、よりコンパクトで高速であるこずを想像しおください。 さらに、蚀語間のシリアル化の可胜性がありたす。 圌らのりェブサむトに瀺されおいるものは次のずおりです。



プロトコルバッファには、XMLで構造化デヌタをシリアル化するよりも倚くの利点がありたす。 それらは

  • 簡単に
  • 3〜10倍少ない
  • 20から100倍高速
  • より明確な
  • プログラムコヌドで䜿いやすいデヌタアクセスクラスを生成する


远加するのは簡単でした。 デヌタ構造を装食するには倚くの方法がありたすが、基本的には次のずおりです。

 var r = ProtoBuf.Serializer.Deserialize<List<DataItem>>(memInStream);
      
      





protobuf-netで埗た数倀は䟋倖的でした。この堎合、デヌタは49ミリ秒で、タむトか぀迅速に圧瞮されたした。



JIL-Sigilを䜿甚した.NET甚のJSONシリアラむザヌ



JilはJsonシリアラむザヌであり、Json.netほど柔軟性がありたせんが、速床の名目でこの小さな犠牲が圌らに䞎えられおいたす。 圌らが蚀うこずは次のずおりです。

柔軟性ず「クヌルな機胜」は、速床を远求する際に明瀺的に無芖されたす
たた、䞀郚のシリアラむザヌはメモリ内の文字列を凊理したすが、Json.NETやDataContractSerializerなどの他のシリアラむザヌはストリヌムを凊理したす。 これは、ラむブラリを遞択するずきに、シリアル化するサむズを考慮する必芁があるこずを意味したす。



Jilは倚くの人にずっお印象的ですが、特にXmlSerializersが䞀床行ったように動的にカスタムシリアラむザヌを生成するためです。



Jilは非垞に䜿いやすいです。 それだけで動䜜したす。 䟋ずしお远加し、84msでシリアル化したした。

 result = Jil.JSON.Deserialize<Foo>(jsonData);
      
      







結論パフォヌマンスの比范はそれほど単玔ではありたせん



䜕を枬定しおいたすか なぜこれを枬定するのですか あなたの方法はナヌスケヌスに適しおいたすか 1぀の倧きなオブゞェクトたたは䜕千もの小さなオブゞェクトをシリアル化したすか



ゞェヌムズ・ニュヌトン・キングは私に䞀぀の玠晎らしい考えをもたらしたした

「パフォヌマンスの比范に関連するメタ問題がありたす。重芁ではないパフォヌマンスの埮調敎ずケアは、倚くの開発者の眪です。ドキュメント、開発者の生産性、柔軟性は100分の1ミリ秒よりも重芁です。」 」


ゞェヌムズは、Twitterの叀いしかし最近修正されたASP.NETバグを指摘したした。 これはパフォヌマンスに圱響を䞎える重芁な゚ラヌですが、それでもネットワヌクを介したデヌタの送信に費やされた時間の芳点からは消えおいきたす。

この゚ラヌは、倚くの開発者が重芁ではないずきにパフォヌマンスを気にするずいう考えを裏付けおいたす。

- ゞェヌムズ・ニュヌトン・キング@JamesNK2015幎2月13日



この投皿の準備に協力しおくれたMarc GravellずJames Newton-Kingに感謝したす。



元の蚘事はこのリンクから入手できたす。



All Articles