山本です。

dir.c と win32\dir.h と win32\win32.c にパッチを当てます。

変更点

1. _findfirst は同時にディレクトリ情報を得られるので、それを使う
   ことで大幅に高速化
2. direntを拡張し、d_isdirフィールドを追加。
   DIR,opendir,readdir,rewinddir,closedirに、これに伴うコード追加。

dir.cが美しくなくなるので心苦しいのですが、
速度は全然違うので、是非取り込んで欲しいです。

# 他の環境でも同様に高速化できれば、罪悪感も減るんですけど。。。

//////////////////////////////////////////////
// dir.c 

# 先ほどの[ruby-dev:22449]に対するパッチです。
# ifndef が美しくない・・・

--- dir.c-22449	Mon Dec 29 21:15:52 2003
+++ dir.c	Mon Dec 29 22:11:22 2003
@@ -1072,4 +1072,8 @@ glob_helper(path, sub, separator, flags,
 	    is_dir = no;
+#ifndef _WIN32
 	    if (do_lstat(buf, &st) == 0) {
 		if (S_ISDIR(st.st_mode)) {
+#else
+	    if (dp->d_isdir) {
+#endif
 		   strcpy(buf+n2, "/**/");
@@ -1078,2 +1082,3 @@ glob_helper(path, sub, separator, flags,
 		   is_dir = ok;
+#ifndef _WIN32
 		}
@@ -1082,2 +1087,3 @@ glob_helper(path, sub, separator, flags,
 		}
+#endif
 	    }
@@ -1100,3 +1106,7 @@ glob_helper(path, sub, separator, flags,
 	    }
+#ifndef _WIN32
 	    else {
+#else
+	    else if (dp->d_isdir) {
+#endif
 		tmp = ALLOC(struct d_link);


//////////////////////////////////////////////
// win32/dir.h

--- win32/dir.h	Tue Jun 11 15:58:56 2002
+++ win32/dir.h	Mon Dec 29 17:00:38 2003
@@ -12,2 +12,3 @@ struct direct
     char d_name[256];
+    char d_isdir;
 };
@@ -19,2 +20,4 @@ typedef struct {
     struct direct dirstr;
+    char *bits;
+    long bitpos;
 } DIR;

//////////////////////////////////////////////
// win32/win32.c

--- win32/win32.c	Thu Nov 27 18:16:48 2003
+++ win32/win32.c	Mon Dec 29 17:09:28 2003
@@ -1386,2 +1386,4 @@ rb_w32_opendir(const char *filename)
     strcpy(p->start, fd.name);
+    p->bits = ALLOC_N(char, 1);
+    p->bits[0] = fd.attrib & _A_SUBDIR ? 1 : 0;
     p->nfiles++;
@@ -1409,2 +1411,14 @@ rb_w32_opendir(const char *filename)
 	strcpy(&p->start[idx], fd.name);
+
+	if (p->nfiles % 8 == 0) {
+	    Renew (p->bits, p->nfiles / 8 + 1, char);
+	    if (p->bits == NULL) {
+		rb_fatal ("opendir: malloc failed!\n");
+	    }
+	    p->bits[p->nfiles / 8] = 0;
+	}
+	if (fd.attrib & _A_SUBDIR) {
+	    p->bits[p->nfiles / 8] |= (1 << p->nfiles % 8);
+	}
+
 	p->nfiles++;
@@ -1446,2 +1460,8 @@ rb_w32_readdir(DIR *dirp)
 	//
+	// Directory flag
+	//
+	dirp->dirstr.d_isdir = dirp->bits[dirp->bitpos / 8] & (1 << dirp->bitpos % 8);
+	dirp->bitpos++;
+
+	//
 	// Now set up for the next call to readdir
@@ -1488,2 +1508,3 @@ rb_w32_rewinddir(DIR *dirp)
 	dirp->curr = dirp->start;
+	dirp->bitpos = 0;
 }
@@ -1498,2 +1519,3 @@ rb_w32_closedir(DIR *dirp)
 	free(dirp->start);
+	free(dirp->bits);
 	free(dirp);