LoginSignup
1
1

More than 1 year has passed since last update.

【python】pathlibはglobより早いのか?

Last updated at Posted at 2021-12-15

結論

特に早くも遅くもないです。
とても身にならない結果です。
私の書き方が良くないのだと思いますが。

事の発端

あるところに二匹のglobがおりました。
こっちがAくん。

dir_a = glob.glob(os.path.join(tar_dir, "*" , "*" ,"*.xlsx*") )

こっちがBくんです。

dir_b = glob.glob(os.path.join(tar_dir, "*" , "*" ,"*" ,"*.xlsx*"))

およそ処理はAくんだけで事足りるのですが、フォルダの構造を見たビビリな作者は突如Bくんを参戦させることにしました。
そんなふたりの実行速度はAくんが約5秒、Bくんが約30秒です。

いや遅すぎでしょ

というわけでもうちょい早くならんかなと作者は少しだけ悩むことにしました。

pathlibという存在を知る

でも、ファイル一覧取得系を調べるとglob+osの方がよく出てくる気もする。
けれども、pathlibの中にもglobがあるらしい。
なおかつglobに比べて可読性が良いことを取り上げている記事もある。

pathlibとかいう優秀すぎる標準ライブラリ(python)

というわけで
なんだか強そうな雰囲気があるpathlibならもうちょい早くなるかしらん?
なノリでれっつら計測。

謎に悩んだところ

しかしクソ雑魚コピペプログラマ(それはプログラマなのか?)は最初の一歩目で躓いた!

>>> list(pathlib.Path(tar_dir, "*" , "*","*.xlsx*").glob("*.xlsx"))

OSError: [WinError 123] ファイル名ディレクトリ名またはボリューム ラベルの構文が間違っています

正しくはこう↓

>>> list(tar_dir.glob(os.path.join("*", "*", "*.xlsx"  )))

pathlibは最初のpath指定するところにワイルドカードを入れるものではないらしい。
たしかに言われてみればglobの時は直接ワイルドカード指定してたから、glob部分に条件書くのがそれっぽい気がする。

……ドキュメント読んでいないのがバレてしまうな!

速度検証

環境はwindows10のpython3系です。
pathlib自体3.4以降でないと使えない人らしいのですけども。

従来のglob+osの書き方とpathlib+osの書き方で下記の3パターンを見てみます。
①フォルダ決め打ち
②ネスト2つ
③ネスト3つ

探るフォルダ情報調べるの忘れてた……。
なお、末尾には役に立たないリストの長さを添えています。
なんで書いてるの?

glob+os版

>>> # -----①フォルダ決め打ち(glob+os)
>>> 
>>> start = time.time()
>>> dir_a = glob.glob(os.path.join(tar_dir, "TMP" , "tst_src" ,"*.xlsx*") )
>>> end_time = time.time() - start
>>> print("elapsed time: {:,.3f} sec".format(end_time))
elapsed time: 0.143 sec
>>> len(dir_a)
6
>>> 
>>> 
>>> # -----②ネスト2つ(glob+os)
>>> 
>>> start = time.time()
>>> dir_b = glob.glob(os.path.join(tar_dir, "*" , "*" ,"*.xlsx*") )
>>> end_time = time.time() - start
>>> print("elapsed time: {:,.3f} sec".format(end_time))
elapsed time: 8.257 sec
>>> len(dir_b)
51
>>> 
>>> 
>>> # -----③ネスト3つ(glob+os)
>>> 
>>> start = time.time()
>>> dir_c = glob.glob(os.path.join(tar_dir, "*" , "*" ,"*" ,"*.xlsx*") )
>>> end_time = time.time() - start
>>> print("Elapsed time: {:,.3f} sec".format(end_time))
Elapsed time: 28.006 sec
>>> len(dir_c)
59

pathlib+os版

>>> # -----①フォルダ決め打ち(pathlib+os)
>>> 
>>> start = time.time()
>>> pa =  =r"C:\HOGE\HUGA\TMP\tst_src"
>>> a = list(pathlib.Path(pa).glob("*.xlsx"))
>>> end_time = time.time() - start
>>> print("elapsed time: {:,.3f} sec".format(end_time))
elapsed time: 0.116 sec
>>> len(a)
6
>>> 
>>> 
>>> # -----②ネスト2つ(pathlib+os)
>>> 
>>> start = time.time()
>>> pa = Path(tar_dir, "HOGE" , "HUGA"  )
>>> aa = list(pathlib.Path(pa).glob(os.path.join("*", "*", "*.xlsx"  )))
>>> end_time = time.time() - start
>>> print("elapsed time: {:,.3f} sec".format(end_time))
elapsed time: 8.121 sec
>>> len(aa)
51
>>> 
>>> 
>>> # -----③ネスト3つ(pathlib+os)
>>> 
>>> start = time.time()
>>> pa = Path(tar_dir, "HOGE" , "HUGA"  )
>>> aaa = list(pa.glob(os.path.join("*", "*","*", "*.xlsx"  )))
>>> end_time = time.time() - start
>>> print("elapsed time: {:,.3f} sec".format(end_time))
elapsed time: 29.939 sec
>>> len(aaa)
59

結果

組み合わせ ①フォルダ決め打ち ②ネスト2つ ③ネスト3つ
glob+os 0.143 sec 8.257 sec 28.006 sec
pathlib+os 0.116 sec 8.121 sec 29.939 sec

特に早くも遅くもない微妙な結果になりました!
ていうかむしろ遅くなって……ない?

まとめ

ワイルドカード使わなければええんちゃうっていうかなんていうか。
この前見たとき5秒だったのが8秒になってるから回線の詰まり具合もあるのかもしれない!

というわけで、この書き方だと速度アップ見込めないのでひとまず現状維持します。
もっと頭の良さそうな検証見たいな……。
探せばありそうだけど。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1