BCL easyPDF SDKていうののベンチマーク取ってみた
画像をPDFに変換するのっていろいろなやり方があると思うけど、easyPDFていうソフトもそういう機能がある。で、easyPDFはWindowsのCOMとして動作するかなり変態的*1なソフト。COMとして呼び出せるってことはどっからでも呼び出せる*2ってことで、夢が広がるじゃないですかー。どのくらい性能でるのかベンチマーク取ってみた。
ベンチマークのルール
jpeg画像をあらかじめ連番で1万件作っておく。名前は0000.jpg〜9999.jpgとする。0000.jpg〜9999.jpgをそれぞれPDFに変換する。名前は0000.pdf〜9999.pdfとする。このPDF変換にかかった時間を計測する。マシンのスペックはこんな感じ。
OS: Windows 7 , 64 bit Build 7601 Service Pack 1 CPU:total 4 (2 cores per cpu, 2 threads per core) family 6 model 37 stepping 2, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, ht ※Intel(R) Core(TM) i3 CPU 540 @ 3.07GHz Memory: 4k page, physical 3923448k(1523204k free), swap 7845044k(4954616k free) vm_info: Java HotSpot(TM) 64-Bit Server VM (20.7-b02) for windows-amd64 JRE (1.6.0_32-b05), built on Apr 5 2012 13:39:03 by "java_re" with MS VC++ 8.0 (VS2005)
プログラム
こんな感じのプログラムを作って実行してみた。Javaのスレッドを利用してる。32スレッドを非同期で*3実行して、1万件のファイルを32スレッドで分担して処理する。
import com.bcl.easypdf.*; import com.bcl.easypdf.EasyPDFPrinter.*; import java.io.File; class PrintPDF { public static void main(String[] args) { long timeMillisStart = System.currentTimeMillis(); // スレッドを32個作成する MyThread[] threads = new MyThread[32]; for (int i = 0; i < 32; i++) { threads[i] = new MyThread(i); threads[i].start(); } // スレッドがすべて終了するのを待つ for (int i = 0; i < 32; i++) { try { threads[i].join(); } catch (InterruptedException e) { System.out.println(e); } } long timeMillisEnd = System.currentTimeMillis(); long time = timeMillisEnd - timeMillisStart; System.out.println(time + "ms. " + time/1000 + "s" ); } } // スレッド class MyThread extends Thread { int threadNo; MyThread(int i){ threadNo = i; } public void run(){ for(int i = 0; i < 10000; i++){ if(i % 32 == threadNo){ String input = String.format("%04d.jpg", i); File inputFile = new File(input); String inputFileName = ""; try { inputFileName = inputFile.getCanonicalPath(); } catch (java.io.IOException e){ e.printStackTrace(); } System.out.println(inputFileName); String output = String.format("%04d.pdf", i); File outputFile = new File(output); String outputFileName = ""; try { outputFileName = outputFile.getCanonicalPath(); } catch (java.io.IOException e){ e.printStackTrace(); } System.out.println(outputFileName); EasyPDF.initialize(); IPrinter printer = new IPrinter(); IPrintJob pj = printer.getPrintJob(); pj.PrintOut(inputFileName, outputFileName); EasyPDF.uninitialize(); } } } }
結果
C:\Users\hide\Documents>java PrintPDF
〜途中省略〜
C:\Users\hide\Documents\9868.jpg
C:\Users\hide\Documents\9868.pdf
C:\Users\hide\Documents\9900.jpg
C:\Users\hide\Documents\9900.pdf
C:\Users\hide\Documents\9932.jpg
C:\Users\hide\Documents\9932.pdf
C:\Users\hide\Documents\9964.jpg
C:\Users\hide\Documents\9964.pdf
C:\Users\hide\Documents\9996.jpg
C:\Users\hide\Documents\9996.pdf
253235ms. 253s
253秒かかった。だいたい4分ちょい。非同期で実行してるので、最後が9999になるとは限らないってことっすね。念のため全件できてるか確認してみる。
C:\Users\hide\Documents>dir *.pdf 〜途中省略〜 2012/05/05 00:54 394,675 9990.pdf 2012/05/05 00:54 394,675 9991.pdf 2012/05/05 00:54 394,675 9992.pdf 2012/05/05 00:54 394,675 9993.pdf 2012/05/05 00:54 394,675 9994.pdf 2012/05/05 00:54 394,675 9995.pdf 2012/05/05 00:54 394,675 9996.pdf 2012/05/05 00:54 394,675 9997.pdf 2012/05/05 00:54 394,675 9998.pdf 2012/05/05 00:54 394,675 9999.pdf 10000 個のファイル 3,946,750,000 バイト 0 個のディレクトリ 60,342,808,576 バイトの空き領域
できてるっぽい。この処理してる間、タスクマネージャーでCPU使用率見てみた。4コア全てで100%に張り付く感じで推移してた。そのほとんどをJavaのプロセスが占めてて、easyPDFのプロセスは1%程度だった。
スレッド数について
スレッド数をなんで32個にしたかというと、あんまり増やすとException吐いて変換できないことがあるから。だいたい47個を超えるとException吐く感じ。たぶん47個くらいまでならいけるんじゃないかなー、と思う。4コアなので4の倍数ということで32個にしてみた。ちなみに1000スレッドとかにするとクラッシュダンプ吐いてJVMが死ぬ。あ、1000スレッドとかにしても、synchronized付ければ安定する。するけど、直列で実行されることになるので意味ない。