Python Developers Festa 2013.11 での発表資料です。
https://github.com/pyspa/pyfes/blob/develop/201311.rst
性能計測結果は Solaris 系の OpenIndiana 151a 上で実施したものですので、他の OS の場合は異なる傾向となる可能性もあります。
3. O 藤原 克則
(FUJIWARA Katsunori)
O ホームページ
http://www.lares.dti.ne.jp/~foozy/index.ja.html
O ブログ
http://d.hatena.ne.jp/flying-foozy/
O Twitter
@flyingfoozy
6. O Solaris 上で稼働させる
HPC 向けファイルシステムの実装などを
仕事でやっていたことも
O 「Tokyo OpenSolaris 勉強会」 で
Solarisカーネルの実装に関する勉強とか
http://www.opensolaris.gr.jp/study.html
O 下位レイヤの話も好き
13. 例えばこんな感じ?
import os
for e in os.listdir(path):
fullpath = os.path.join(path, e)
if os.path.isdir(fullpath):
# ディレクトリに対する処理
elif os.path.isfile(fullpath):
# ファイルに対する処理
.....
16. 多少コスト意識が
ある場合は….
import os, stat
for e in os.listdir(path):
fullpath = os.path.join(path, e)
st = os.lstat(fullpath)
if stat.S_ISDIR(st.st_mode):
# ディレクトリに対する処理
elif stat.S_ISREG(st.st_mode)
# ファイルに対する処理
.....
22. ファイル名解決における
間接的なコスト
O 階層/配下要素の増加による I/O 量の増加
O メモリアクセスと比べて、
圧倒的にコストが高い
O I/O 対象の散在によるシークコストの増加
O 記録媒体が HDD であれば、
ミリ秒単位の I/O 待ち状態
O GHz クラスの CPU なら、
単純計算でも百万命令単位分の I/O 待ち
24. 低減策 (1) ~
os.lstat() 呼び出しの低減
O readdir(3) が返す struct dirent には
各要素の種別情報を保持する
d_type フィールドがある
O 種別情報のみで事足りるなら
lstat(2) 呼び出し自体が不要
25. 低減策 (2) ~
ファイル名解決コストの低減
O fstatat(2) システムコールの利用
O SYNOPSYS
int fstatat(int dfd,
const char *path, struct stat *buf,
int flag);
O 起点ディレクトリ(dfd)からの相対的名前解決
O 直下の要素なら問い合わせは1階層限定
O I/O対象を局所化可能
32. 環境毎の仕様準拠
O dirent.d_type による種別情報の提供は
POSIX 標準ではオプション扱い
O GNU coreutils の ls でも
使用可能な環境では使用
O fstatat(2) の標準化は XPG7 (2013) から
O XPG7 非準拠なら、サポートの必要無し
(とは言うものの多くの環境で利用可能)
O GNU coreutils の ls では未使用
38. O ディレクトリ配下要素の
情報取得を行う機能 osutil.listdir() を
MercurialではCライブラリとして独自実装
O システムコール実行コストを
環境に応じて極力低減
O DT_REG マクロ判定
(dirent.d_type 利用の可否)
O AT_SYMLINK_NOFOLLOW マクロ判定
(fstatat(2) 利用の可否)
O Cライブラリ連携を使用できない環境向けに
pure Python 版 osutil もあるが
性能的には当然Cライブラリ実装よりも遅い
40. ls.c は読まなくても….
O mercurial/osutil.c の listdir() 実装は
読んでおいた方が良いかもね!
O ディレクトリ要素や要素毎情報の取得で
使用している API を把握しよう
O API 使い分けによる
性能への影響を理解しよう
O POSIX環境向けと Windows環境向け実装が
同一ファイル中にあるので参照時は注意