XML Mark 1.1 on .NET2.0 RTM

同一環境上において.NETとJavaのプログラム実行性能を手軽に比較できて、それでいてどちらかのプラットホームにバイアスが掛かっていないベンチマーク(指標)を探していたが、XML処理性能に限定される、という制限はあるが、いろいろな所で紹介されているXMLMarkがよさげだったので、同ベンチマークを使用して.NET2.0の性能をJava及び.NET1.1のそれと比較してみた。

XML Test 1.0 XML Processing Performance in Java and .NET code sample
Comparing XML Performance .NET 2.0 Beta2, .NET 1.1, and Sun Java 1.5 Platforms
(Sunのリンクではより実務に近いテストケースとして、Webサービス(SOAP)を使用した際の性能を比較するテストキットも公開されているが、そちらを使うとアプリケーションサーバ等の余計な要素が増えるし、セットアップも面倒なので、今回は単純にXMLの処理を比較するXML Markを使用することにした。)

両方のリンクを辿って落とせるテスト用のコードとバイナリは殆ど同じ物であるが、Sunが公開しているXML Mark 1.0にはMicrosoft側から見るといくつかの問題点があったようで、Microsoftはその点をFixしたバージョンとして独自にXML Mark 1.1として公開している所に注意が必要だ。

XML Mark1.0 -> 1.1でMicrosoft側が考慮した点

1.The java code included in their kit has a bug that results in no serialization (save to disk) occurring in the java tests even when the run properties are set to serialize the XML test document, while the .NET implementation properly saves to disk when the serialization parameter is set.

2.We also found that Sun is using the GetElementsByTagName method in C#, and this results in a mismatch of the C# and Java versions. Although both harnesses use XmlElement.GetElemensByTagName(), the C# implementation of this method keeps track of a live list of nodes which is negatively impacted by some of the DOM test scenarios that have edits. A better method for element selection in the C# harness is XmlElement.SelectNodes() which matches the Java harness in functionality.

1.テスト用プラットホーム

普段使用しているサーバ上で全てのテストを実施した。

  • 2x1.8GHZ Intel Xeon Processors (HyperThreading Enable)
  • 2GB of RAM
  • 17GBx2 SCSI Drive
  • Windows XP Professional Edition with SP2
  • .NET v1.1.4322 with SP1
  • .NET v2.0.50727 (RTM)
  • Sun J2SE1.4 (Hotspot Client VM build 1.4.2_09-b05

テストは添付されているバッチファイルを起動することで全てのテストを自動的に実行する。テストアプリケーションはテストのスペックを記述したINIファイルを内部に取り込んで、テストスペックに則ったテストを一度行い、結果をファイルで出力する。テストのスペックは\iniフォルダに配置しておきバッチファィルで、次々とファイルを読込むことで複数のテストを実行している。.NETは実行アセンブリを直接起動しており、Javaはテストを実行するためのAntタスクを起動している。

実際には以下のようなバッチファイルでテストを実行している(run_xmlmark.bat)

@echo off
rem Run Java and C# tests 
call xmlmarkenv.bat
if "%JAVA_HOME%" == "" goto end_exit
if "%ANT_HOME%" == "" goto end_exit
if "%XMLMARK_HOME%" == "" goto end_exit
pushd %XMLMARK_HOME%\C#\bin
for %%g in (%XMLMARK_HOME%\ini\xmlmark_*.ini)  do .\XMLmark %%g
popd
rem Run the Java part
for %%f in (%XMLMARK_HOME%\ini\xmlmark_*.ini) do ant -f %XMLMARK_HOME%\Java\src\xmlmark.xml run-xmlmark -DiniFile=%%f
goto end
:end_exit
echo Please set the environment variable in xmlmarkenv.bat.
:end

すんなり動くと思ったのだが、私の環境ではいろいろと問題が発生したので個別に対処した

2.テストを実行する前に行った作業

Java側のAntタスクを起動するバッチファイルのfor文に問題があり動作しなかったのを修正した。
Javaのクラスファイル(.class)はJ2SE1.5用にビルドされており自分の環境では動作しなかった。-> 使用するJSDKでリビルドした。
・.NETのアセンブリは.configファイルでランタイムバージョンにβ2(v2.0.50215)が指定されていたので、テストの際には現在のRTMのビルドである(v2.0.50727)に変更した。
・.NET2.0上での実行に関しては一応Visual Studio 2005 Professional 英語版にてビルドも行っている。以前の日記「XmlValidatingReader is now obsolete」でも言及したが、XMLReaderが全面的にファクトリパターンに移行したため大量にワーニングが出たが、コードにはできるだけ手を入れたくなかったので今回は無視している。

3.テスト結果

XMLMark 1.1でのテスト仕様は、100行、又は1000行のXMLをDOMツリーに変換していろいろな処理を行うDOM Testが6通り、SAXパーサ(.NETの場合はプルパーサ?)でアクセスするSAX Testが3通り用意されている。全てのテストを行うと2時間程度かかるらしいので、まずは試しに重めのDOM Testを二つ(DOM3, DOM6)とSAX Test(SAX3)を一つ行った結果を採ってみた。
(それぞれのテストの仕様の細かい説明に関しては冒頭のMicrosoftのハイパーリンクを参照)



一目で解るのはJ2SE1.4は.NET1.1より速いということ。.NETはJavaとは違い、最初からXML処理に関しては重きを置いていたので、てっきり.NETの方が速いと思ったのだが実際はJavaの方が速い。これは長い間積み重ねた改良の成果と見ることができる。あとは.NET1.1から.NET2.0に至る性能の改善が著しい点。全く同じ環境上でILも同一で、CLRだけを切替えただけでこれだけの性能差が出るのはちょっと凄いと思う。.NET1.1から2.0に乗り換える意味を見いだせない場合の一助になるかもしれない。

個人的には似たような環境で.NETにMONOを使用したテスト結果も見てみたいな。

追記

・.NET2.0上での実行に関しては一応Visual Studio 2005 Professional 英語版にてビルドも行っている。以前の日記「XmlValidatingReader is now obsolete」でも言及したが、XMLReaderが全面的にファクトリパターンに移行したため大量にワーニングが出たが、コードにはできるだけ手を入れたくなかったので今回は無視している。

と書いたが、Visual Studio 2003上でビルドした.NET1.1用のアセンブリを.NET2.0 CLR(v2.0.50727)上で動かしたテスト結果と、Visual Studio 2005でビルドした.NET2.0用のアセンブリを.NET2.0 CLR上で動かしたテストした結果の間には、有効な差異は見られなかった。あと、当たり前の現象だが.NET1.1上で動作することを確認したコードを、Visual Studio 2005でビルドして、.NET1.1用のCLR上で動かそうとしたが、「形式が違う」というエラーを吐いて動かなかった。