[macruby-changes] [2966] MacRuby/trunk/io.c
source_changes at macosforge.org
source_changes at macosforge.org
Thu Nov 5 23:02:16 PST 2009
Revision: 2966
http://trac.macosforge.org/projects/ruby/changeset/2966
Author: lsansonetti at apple.com
Date: 2009-11-05 23:02:15 -0800 (Thu, 05 Nov 2009)
Log Message:
-----------
faster IO#gets
Modified Paths:
--------------
MacRuby/trunk/io.c
Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c 2009-11-06 07:01:44 UTC (rev 2965)
+++ MacRuby/trunk/io.c 2009-11-06 07:02:15 UTC (rev 2966)
@@ -935,6 +935,19 @@
}
}
+static inline void
+rb_io_read_update(rb_io_t *io_struct, long len)
+{
+ io_struct->buf_offset += len;
+
+ lseek(io_struct->read_fd, io_struct->buf_offset, SEEK_SET);
+
+ if (io_struct->buf_offset == CFDataGetLength(io_struct->buf)) {
+ CFDataSetLength(io_struct->buf, 0);
+ io_struct->buf_offset = 0;
+ }
+}
+
static inline long
rb_io_read_internal(rb_io_t *io_struct, UInt8 *buffer, long len)
{
@@ -945,7 +958,8 @@
if (fstat(io_struct->read_fd, &buf) == -1 || buf.st_size == 0
|| lseek(io_struct->read_fd, 0, SEEK_CUR) > 0) {
// Either a pipe, stdio, or a regular file that was seeked.
- return read_internal(io_struct->read_fd, buffer, len);
+ return len == 0
+ ? 0 : read_internal(io_struct->read_fd, buffer, len);
}
// TODO don't pre-read more than a certain threshold...
@@ -966,13 +980,8 @@
const long n = len > s - io_struct->buf_offset
? s - io_struct->buf_offset : len;
memcpy(buffer, CFDataGetBytePtr(io_struct->buf) + io_struct->buf_offset, n);
- io_struct->buf_offset += n;
- lseek(io_struct->read_fd, io_struct->buf_offset, SEEK_SET);
- if (io_struct->buf_offset == s) {
- CFDataSetLength(io_struct->buf, 0);
- io_struct->buf_offset = 0;
- }
+ rb_io_read_update(io_struct, n);
return n;
}
@@ -1285,37 +1294,69 @@
}
}
else {
- long s = 512;
- CFDataSetLength(data, s);
-
const char *sepstr = RSTRING_PTR(sep);
- const int seplen = RSTRING_LEN(sep);
+ const long seplen = RSTRING_LEN(sep);
assert(seplen > 0);
- UInt8 *buf = CFDataGetMutableBytePtr(data);
- UInt8 *tmp_buf = alloca(seplen);
- long data_read = 0;
- while (true) {
- if (rb_io_read_internal(io_struct, tmp_buf, seplen) != seplen) {
- break;
+ // Pre-cache if possible.
+ rb_io_read_internal(io_struct, NULL, 0);
+ if (io_struct->buf != NULL && CFDataGetLength(io_struct->buf) > 0) {
+ // Read from cache (fast).
+ const UInt8 *cache = CFDataGetMutableBytePtr(io_struct->buf)
+ + io_struct->buf_offset;
+ const long cache_len = CFDataGetLength(io_struct->buf)
+ - io_struct->buf_offset;
+ const UInt8 *pos = cache;
+ long data_read = 0;
+ while (true) {
+ const UInt8 *tmp = memchr(pos, sepstr[0], cache_len);
+ if (tmp == NULL) {
+ data_read = cache_len;
+ break;
+ }
+ if (seplen == 1
+ || memcmp(tmp + 1, &sepstr[1], seplen - 1) == 0) {
+ data_read = tmp - cache + seplen;
+ break;
+ }
+ pos = tmp + seplen;
}
- if (data_read >= s) {
- s += s;
- CFDataSetLength(data, s);
- buf = CFDataGetMutableBytePtr(data);
+ if (data_read == 0) {
+ return Qnil;
}
- memcpy(&buf[data_read], tmp_buf, seplen);
- data_read += seplen;
+ CFDataAppendBytes(data, cache, data_read);
+ rb_io_read_update(io_struct, data_read);
+ }
+ else {
+ // Read from IO (slow).
+ long s = 512;
+ long data_read = 0;
+ CFDataSetLength(data, s);
- if (memcmp(tmp_buf, sepstr, seplen) == 0) {
- break;
+ UInt8 *buf = CFDataGetMutableBytePtr(data);
+ UInt8 *tmp_buf = alloca(seplen);
+
+ while (true) {
+ if (rb_io_read_internal(io_struct, tmp_buf, seplen) != seplen) {
+ break;
+ }
+ if (data_read >= s) {
+ s += s;
+ CFDataSetLength(data, s);
+ buf = CFDataGetMutableBytePtr(data);
+ }
+ memcpy(&buf[data_read], tmp_buf, seplen);
+ data_read += seplen;
+
+ if (memcmp(tmp_buf, sepstr, seplen) == 0) {
+ break;
+ }
}
+ if (data_read == 0) {
+ return Qnil;
+ }
+ CFDataSetLength(data, data_read);
}
-
- if (data_read == 0) {
- return Qnil;
- }
- CFDataSetLength(data, data_read);
}
OBJ_TAINT(bstr);
io_struct->lineno += 1;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091105/cbe36ddd/attachment.html>
More information about the macruby-changes
mailing list