[Mew-dist 16232] Re: directory-files is too slow
Kenichi Handa
handa at example.com
2001年 2月 7日 (水) 21:53:36 JST
Kazu Yamamoto (山本和彦) <kazu at example.com> writes:
> Emacs 21.0.97 の directory-files はとても遅いです。15721 個ファイルを
> 格納するディレクトリに対し、directory-files を実行し、プロファイルをとっ
> てみると添付資料のようになります。(FreeBSD/NetBSD 両方で同じ結果になり
> ました。)
> *** Emacs 21.0.97 は Emacs 20.7 の 20 倍ぐらい遅いようです。***
あ、 mule at example.com の方には流していたと思うんですが、この主
な原因は lisp.h に
#define GC_CHECK_STRING_BYTES 1
というデバッグ用の定義があるためです。これがあると Lisp
string を作るたびに全ての string の整合性をチェックするので
遅くなっているのです。この行をコメントにすれば、かなり早くな
るはずです。
> Emacs 21.0.97 の dired.c:directory_files_internal の、
> name = DECODE_FILE (name);
> len = STRING_BYTES (XSTRING (name));
> 部分を外すと、(3) のように 2 倍速くなります。(注:実験した呼び出し方で
> は、この部分は不要。)
これは DECODE_FILE がさらに Lisp string を作っているからです。
> なお、この関数の最後に、
> #ifdef EAGAIN
> retry_p |= errno == EAGAIN;
> #endif
> #ifdef EINTR
> retry_p |= errno == EINTR;
> #endif
> というコードがありますが、個人的にはあまり感心しません。
> まず、エラーが起っていることを確かめた後に、errno を参照すべきです。ど
> のシステムコールのエラーを拾おうとしているのか、不明瞭に思います。(こ
> の部分が、directory_files_internal の速度に影響を及ぼしていない、つま
> り retry していないことは確かめました。)
確かにそうですね。ところで readdir が NULL を返したときend
of directory と エラーをどうやって区別したら良いんでしょう。
Solaris 2.6 のマニュアルには、
RETURN VALUES
Upon successful completion, readdir() and readdir_r() return
a pointer to an object of type struct dirent. When an error
is encountered, a null pointer is returned and errno is set
to indicate the error. When the end of the directory is
encountered, a null pointer is returned and errno is not
changed. The POSIX readdir_r() returns 0 if successful or
an error number to indicate failure.
と書いてあり、これを読む限りじゃ readdir を call する前に
errno が EAGAIN だったりすると、どうしようもない気がします。
それとも errno ってプログラム側で set しても良いものなんでしょ
うか?
−− けんちゃん@ETL
handa at example.com
Mew-dist メーリングリストの案内