LibreOffice5(78)FilePickerにフィルターを追加する2つの方法の速さを計測する

2017-08-30

旧ブログ

t f B! P L
FilePickerサービスにフィルターを追加する方法には2つあるのでその速さを計測します。結論としてはどちらの方法が速いのかなんとも言えませんでしたが、とりあえずWindows10の画面描画はとても遅いことがわかりました。

前の関連記事:LibreOffice5(77)FilePickerのTemplateDescriptionを実行してみる


FilePickerサービスにフィルターを追加する2つの方法


appendFilter()メソッドは2つの引数をもち、第1引数は表示させるフィルター名、第2引数は*.extといった形式をセミコロンでつないだ拡張子の文字列になります。

フィルター名が複数あるときはフィルター名の数だけappendFilter()メソッドを反復することになります。

これに対してappendFilterGroup()メソッドは、フィルターをタプルで追加できるので1回のメソッドで複数のフィルター名を追加できます。

ところがこれの問題点はタプルに入れるフィルターをStringPair Structにしないといけないことです。

LibreOffice5(76)FilePickerのフィルターを作成: 失敗で使ったsetDataArray()
のようにany型のsequenceであればタプルで渡せるので、ひとつづつ追加するより速度向上が期待できます。

しかし、Structの場合はPythonのデータ型には該当するものがないのでいちいちインスタンス化しないといけません。

この時点でappendFilter()メソッドの方が速いだろうと予測がつきますが、いちおう速度計測することにしました。

timethisデコレーターでメソッドの実行速度を計測する


実行速度の計測にはPython Cookbookの例14.13.profiling_and_timing_your_programのtimethisデコレーターを使います。
(2017.9.2追記Python(25)実行時間を計測する方法で既にtimeitモジュールを使った方法をやっていますね。どちらもtime.perf_counter()を使っているのは同じのようです。今回の方法とどう違うのでしょう。)
def timethis(func):
 doc = XSCRIPTCONTEXT.getDocument()  # Writerドキュメントを取得。
 @wraps(func)
 def wrapper(*args, **kwargs):
  start = time.perf_counter()
  r = func(*args, **kwargs)
  end = time.perf_counter()
  doctext = doc.getText().getString()  # すでにドキュメントにある文字列を取得。
  doc.getText().setString('{}\n{}.{} : {}'.format(doctext, func.__module__, func.__name__, end-start))  # Writerドキュメントに出力。 上書き。 
#   print('{}.{} : {}'.format(func.__module__, func.__name__, end-start))
  return r
 return wrapper 
マクロではprint()の出力を取得できないのでWriterドキュメントに出力するようにしました。

setString()はWriterドキュメントの内容をすべて上書きしてしまうので、まずgetString()ですでにある内容を取得して、それに追記したものを上書きしています。
def macro():  # オートメーションでFilePickerサービスをインスタンス化するとクラッシュする。
 ctx = XSCRIPTCONTEXT.getComponentContext()  # コンポーネントコンテクストの取得。
 smgr = ctx.getServiceManager()  # サービスマネージャーの取得。
 templateurl = ctx.getByName('/singletons/com.sun.star.util.thePathSettings').getPropertyValue("Work")  # デフォルトで表示するフォルダを取得。
 filters = {'WordPerfect Graphics': '*.wpg', 'SVM - StarView Meta File': '*.svm', 'PSD - Adobe Photoshop': '*.psd', 'EMF - Enhanced Meta File': '*.emf', 'PCD - Photo CD Base16': '*.pcd', 'PCD - Photo CD Base': '*.pcd', 'SGF - StarWriter SGF': '*.sgf', 'PGM - Portable Graymap': '*.pgm', 'SVG - Scalable Vector Graphics': '*.svg;*.svgz', 'PPM - Portable Pixelmap': '*.ppm', 'XBM - X Bitmap': '*.xbm', 'PBM - Portable Bitmap': '*.pbm', 'RAS - Sun Raster Image': '*.ras', 'WMF - Windows Metafile': '*.wmf', 'PCD - Photo CD Base4': '*.pcd', 'TGA - Truevision Targa': '*.tga', 'GIF - Graphics Interchange': '*.gif', 'Corel Presentation Exchange': '*.cmx', 'Adobe/Macromedia Freehand': '*.fh;*.fh1;*.fh2;*.fh3;*.fh4;*.fh5;*.fh6;*.fh7;*.fh8;*.fh9;*.fh10;*.fh11', 'CGM - Computer Graphics Metafile': '*.cgm', 'XPM - X PixMap': '*.xpm', 'MET - OS/2 Metafile': '*.met', 'DXF - AutoCAD Interchange Format': '*.dxf', 'JPEG - Joint Photographic Experts Group': '*.jpg;*.jpeg;*.jfif;*.jif;*.jpe', 'TIFF - Tagged Image File Format': '*.tif;*.tiff', 'PNG - Portable Network Graphic': '*.png', 'PCT - Mac Pict': '*.pct;*.pict', 'EPS - Encapsulated PostScript': '*.eps', 'BMP - Windows Bitmap': '*.bmp', 'PCX - Zsoft Paintbrush': '*.pcx'}  # 画像フィルターの辞書。
 filterall = "All Image Files"
 filters[filterall] = ";".join(filters.values())  # すべての画像ファイルをまとめたフィルターを辞書に追加。
 filters["All Files"] = "*.*"  # すべてのファイルのフィルターを辞書に追加。
 filterpicker = appendFilterGroup(ctx, smgr, filters, filterall, templateurl)
 filterpicker.execute()
 filterpicker = appendFilter(ctx, smgr, filters, filterall, templateurl)
 filterpicker.execute()
@timethis
def appendFilterGroup(ctx, smgr, filters, filterall, templateurl): 
 filterpairs = []
 [filterpairs.append(StringPair(First=key, Second=filters[key])) for key in sorted(filters.keys())]
 filepicker = smgr.createInstanceWithArgumentsAndContext("com.sun.star.ui.dialogs.FilePicker", (FILEOPEN_SIMPLE,), ctx)
 filepicker.setDisplayDirectory(templateurl)  # デフォルトで表示するフォルダを設定。設定しないと「最近開いたファイル」が表示される。
 filepicker.appendFilterGroup("Filters", filterpairs)
 filepicker.setCurrentFilter(filterall)  # デフォルトで表示するフィルターを設定。linuxBeanのFILESAVE系では「すべての形式」(*以外のフィルターの拡張子を足したもの)というのが表示されてしまう。
 return filepicker
@timethis 
def appendFilter(ctx, smgr, filters, filterall, templateurl): 
 filepicker = smgr.createInstanceWithArgumentsAndContext("com.sun.star.ui.dialogs.FilePicker", (FILEOPEN_SIMPLE,), ctx)
 filepicker.setDisplayDirectory(templateurl)  # デフォルトで表示するフォルダを設定。設定しないと「最近開いたファイル」が表示される。
 [filepicker.appendFilter(key, filters[key]) for key in sorted(filters.keys())]  # フィルターは追加された順に表示されるのでfiltersをキーでソートしてから追加している。filepicker.setCurrentFilter(filterall)  # デフォルトで表示するフィルターを設定。linuxBeanのFILESAVE系では「すべての形式」(*以外のフィルターの拡張子を足したもの)というのが表示されてしまう。
 filepicker.setCurrentFilter(filterall)  # デフォルトで表示するフィルターを設定。linuxBeanのFILESAVE系では「すべての形式」(*以外のフィルターの拡張子を足したもの)というのが表示されてしまう。
 return filepicker
これが速度計測に使うマクロです。

関数appendFilterGroup()はappendFilterGroup()メソッドを使ってフィルター名を追加しています。

それに対して関数appendFilter()はappendFilter()メソッドを使ってフィルター名を追加しています。

GUI/filepickerappendfilter.py at 136faac2332730bc768f3de4b9db6b56aa04ea66 · p--q/GUI

オートメーション用のコードもつけていますが、FilePikerサービスを実行するとクラッシュするのでデバッグ用にしか使えません。

速度計測結果


ooo_script_framework.appendFilterGroup : 0.04951838799934194
ooo_script_framework.appendFilter : 0.02557123299993691
ooo_script_framework.appendFilterGroup : 0.02557948700086854
ooo_script_framework.appendFilter : 0.03245078600048146
ooo_script_framework.appendFilterGroup : 0.02476496500094072
ooo_script_framework.appendFilter : 0.021140035998541862
ooo_script_framework.appendFilterGroup : 0.029479987000740948
ooo_script_framework.appendFilter : 0.02111495300050592

VirtualBoxのゲストのlinuxBean14.04、LibreOffice5.2での実行結果です。

うーん、どっちが速いのか何とも言えませんね。

ooo_script_framework.appendFilterGroup : 0.09134221299973433
ooo_script_framework.appendFilter : 0.036987366000175825
ooo_script_framework.appendFilterGroup : 0.02661770600025193
ooo_script_framework.appendFilter : 0.05516077799984487
ooo_script_framework.appendFilterGroup : 0.030688196000483003
ooo_script_framework.appendFilter : 0.026037491999886697
ooo_script_framework.appendFilterGroup : 0.031629191998945316
ooo_script_framework.appendFilter : 0.038406735999160446

LibreOffice5.3での結果です。

これも何とも言えませんね。

とりあえず初回の実行はとても時間がかかるということはわかります。

ooo_script_framework.appendFilterGroup : 0.0034784200837809478
ooo_script_framework.appendFilter : 0.0032345653062799684
ooo_script_framework.appendFilterGroup : 0.0035724314373979382
ooo_script_framework.appendFilter : 0.0031709331673681618
ooo_script_framework.appendFilterGroup : 0.003174217406797908
ooo_script_framework.appendFilter : 0.002951299655649109
ooo_script_framework.appendFilterGroup : 0.003654947953016574
ooo_script_framework.appendFilter : 0.0029106571927286495

今度はホストOSのWindows10 64bitのLibreOffice5.2の結果です。

VirtualBoxのゲストOSであるlinuxBeanのときと比べると1桁も時間が短いです。

だけど、実感としてはWindows10の方がダイアログが出現するまでにもっさりと遅い印象です。

FilePickerサービスをインスタンス化してexecute()する手前までの時間を測定した結果はWindows10の方が一桁速いのに、ダイアログがでてくるまではlinuxBeanより遅いので、Windows10ではexecute()が相当遅いようです。

上記はCorei5でやりましたが、Core2にインストールしてあるlinuxBeansで実行してみました。

ooo_script_framework.appendFilter : 0.07259722100002364
ooo_script_framework.appendFilterGroup : 0.014379830999928345
ooo_script_framework.appendFilter : 0.013896669000018846
ooo_script_framework.appendFilterGroup : 0.014223178000065673
ooo_script_framework.appendFilter : 0.013948421999998573
ooo_script_framework.appendFilterGroup : 0.01649581300000591

今度はappendFilter()を先に実行するようにしました。

やっぱり初回は時間がかかるようです。

VirtualBoxのゲストOSと違ってネイティブインストールだと早くなっていますが、桁が変わるほどではないのはCPUの差でしょうか。

次の関連記事:LibreOffice5(79)ダイアログとコントロールコンテナの背景色

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ