From: nobu.nakada@... Date: 2001-07-21T09:43:36+09:00 Subject: [ruby-dev:13964] Re: IO#read なかだです。 At Sat, 21 Jul 2001 05:27:11 +0900, Akinori MUSHA wrote: >  試しに io_fread() を { return fread(ptr, 1, len, f); } にして > みたら、 > > 1.90 real 0.79 user 1.06 sys > > になりました。(!) がちょーん。でかいっすね。とりあえずこんなとこで。 Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.90 diff -u -2 -p -r1.90 io.c --- io.c 2001/07/14 15:17:18 1.90 +++ io.c 2001/07/21 00:40:10 @@ -109,9 +109,12 @@ static VALUE lineno; # ifdef _IO_fpos_t # define READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end) +# define READ_DATA_PENDING_COUNT(fp) ((fp)->_IO_read_end - (fp)->_IO_read_ptr) # else # define READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr) +# define READ_DATA_PENDING_COUNT(fp) ((fp)->_egptr - (fp)->_gptr) # endif #elif defined(FILE_COUNT) # define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0) +# define READ_DATA_PENDING_COUNT(fp) ((fp)->FILE_COUNT) #elif defined(__BEOS__) # define READ_DATA_PENDING(fp) (fp->_state._eof == 0) @@ -477,12 +480,32 @@ io_fread(ptr, len, f) int c; - while (n--) { + while (n > 0) { +#ifdef READ_DATA_PENDING_COUNT + int i = READ_DATA_PENDING_COUNT(f); + if (i <= 0) { + rb_thread_wait_fd(fileno(f)); + i = READ_DATA_PENDING_COUNT(f); + } + if (i > 0) { + if (i > n) i = n; + TRAP_BEG; + c = fread(ptr, 1, i, f); + TRAP_END; + if (c < 0) goto eof; + ptr += c; + n -= c; + if (c < i) goto eof; + continue; + } +#else if (!READ_DATA_PENDING(f)) { rb_thread_wait_fd(fileno(f)); } +#endif TRAP_BEG; c = getc(f); TRAP_END; if (c == EOF) { + eof: if (ferror(f)) { if (errno == EINTR) continue; @@ -493,7 +516,8 @@ io_fread(ptr, len, f) } *ptr++ = c; + --n; } - return len - n - 1; + return len - n; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦