トップ «前の日記(Thu Jan 25 2007) 最新 次の日記(Sat Jan 27 2007)» 編集

よこいまさる日記



Fri Jan 26 2007 [長年日記]

ディレクトリの深さと open|close のパフォーマンスの違いに因果関係があるのかどうかの調査

どこかから coss の調査してみてはどうよ、といわれたのでちまちま調べることにしてみました。 HTTPなどのキャッシュサーバとして用いられている squid に、coss (Cyclic Object storage system) というキャッシュの記憶機構がついており、これのパフォーマンスが良いのって本当かよとか yamazさんのところで語られている のですが、この文章のなかにこんなやり取りが

xxxxx : 3年ぐらい前、apacheをプロファイリングしたら、select()の次にopen()がコストを食ってました。で、そのときは、open("/home/xxxx/hoge/hoge/hoge.gif") とかしたとき、/home, /home/xxxx,...のディレクトリファイルを読みに行って、そこでDISK IOが詰まってるんじゃないか?と思ってました。
yamaz : なかなか説得力あるなw

これのなかの、そもそもディレクトリ階層的に深いところにあるとパフォーマンス落ちるのかどうかを調べてました。 対象のシステムは FedoraCore6 (Linux kernel 2.6.18-1.2798.fc6) というものです。

まずは、こんなPerlスクリプトでディレクトリを適当に掘ってみました。

#!/usr/bin/perl

use Digest::MD5; # set dirname entries my @dirnames; my $depth = 10; my $num_in_dir = 3; for (my $i = 0; $i < $num_in_dir; $i ++) { push(@dirnames, $i); }
mkdir ("./nest"); make_nest_dir("./nest", $depth);
sub make_nest_dir ($$) { my $curdir = shift; my $curnestnum = shift; $curnestnum -= 1; if ($curnestnum) { foreach my $each (@dirnames) { my $dir_mk = "$curdir/$each"; if (!mkdir($dir_mk)) { print STDERR "Can't make directory($dir_mk) : $!\n"; next; } make_nest_dir($dir_mk, $curnestnum); } } system("touch $curdir/file"); print "make : $curdir\n" }

そすると、こんな感じのディレクトリが nest/ 内にできます

0/file
0/0/file
0/0/0/file
....
0/0/0/0/0/0/0/0/0/file
0/0/0/0/0/0/0/0/1/file
.....

この状態で shell の glob の wildcard を使って任意の数のディレクトリとか取ればよい状態にします。 たとえば 0/?/?/?/?/file0/0/0/0/0/?/?/?/?/file でのファイルの open/close をジャンジャンやらせた時の時間の比較をすると。 ちなみにこんなコード使って、open|close の繰り返しをしてみました。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>

void usage (){ printf("openclose_test [count] [files....]\n count: number of open/close for one file\n"); } int main (int argc, char** argv) { int loopc = 0, fd, i, j; if (argc < 3) { usage(); exit(1); } loopc = atoi(argv[1]); if (loopc < 1) { usage(); exit(1); } for (i = 0; i < loopc; i++) { for (j = 2; j < argc; j++) { fd = open(argv[j], O_RDONLY); if (fd < 0) { fprintf(stderr, "Failed to open %s : %s\n", argv[j], strerror(errno)); continue; } close(fd); } } }

で、これで、nest/?/?/?/?/file を 16384回 open/close した場合は8.381秒ぐらいで、nest/0/0/0/0/0/?/?/?/?/file を 16384回 open/close した場合は11秒ぐらいでした。 ディレクトリの深さによってパフォーマンスに変化あることは確かなようです。

宴会

みんなが来るの待っているところ。

Photo 0 (20:42)

本日のツッコミ(全3件) [ツッコミを入れる]
yamaz (Fri Jan 26 2007 08:03)

浅いほうのディレクトリ名を長くしたらどうなる?

まさる (Fri Jan 26 2007 14:44)

同じ深さのディレクトリで、ディレクトリ名だけ長くしたところ(1文字→4文字)、4.90秒かかっていたのが5.08秒かかるようになった、とかいう具合でした。 ちなみにこのテストで使ったディレクトリが /home/masaru/tree/nest/0 とかいう場所だったので、/tmp/nest/tree /0 とかに動かして同じように測定してみたところ、処理時間的にはそれほど変わりなかったです。。。

まさる (Fri Jan 26 2007 17:10)

となると、ディレクトリの文字列が長いほどパフォーマンス悪いみたいです。<br>同じファイルを表す /tmp/nest/0/?/?/?/file と ./0/?/?/?/file で違いを測定してみたところ、./0 のほうが短い時間で終わります。  絶対パスと相対パスでいくと、相対パスのほうが速いのかなぁ。。


2000|10|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|