[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 メーリングリストの案内