From: UENO Katsuhiro Date: 2003-07-16T12:25:06+09:00 Subject: [ruby-list:37882] Re: ERB の仕様 うえのです。 On Wed, 16 Jul 2003 10:52:00 +0900 Shinya Kawaji wrote: > > 1.2MBくらいの素朴なeRubyスクリプトを準備して試したのですが、 > > ruby1.6.8とruby1.8.0だと全く結果が違くて驚きました。 > > 私も高速化に興味があるのですが(興味があるだけで自分で何が出来るのかは > まだ解らないのですが)、もし上記の「1.2MBくらいの素朴なeRubyスクリプト」 以前 eRuby-1.0.3 + Ruby-1.6.8 で Web アプリケーションを書いたとき あまりにも eRuby が遅かったので (かといって 1.8 に上げることは できなかったので)、場当たり的にこんな修正をして凌いだことがあります。 --- eruby_main.c.orig Mon Oct 15 13:55:40 2001 +++ eruby_main.c Sat Mar 1 22:36:51 2003 @@ -376,21 +376,47 @@ } } + +static struct { + char *buf; + int len; + int max; +} eruby_defout; + static VALUE defout_write(VALUE self, VALUE str) { str = rb_obj_as_string(str); - rb_str_cat(self, RSTRING(str)->ptr, RSTRING(str)->len); + if (eruby_defout.len + RSTRING(str)->len > eruby_defout.max) { + while (eruby_defout.len + RSTRING(str)->len > eruby_defout.max) + eruby_defout.max *= 2; + REALLOC_N(eruby_defout.buf, char, eruby_defout.max); + } + memcpy(eruby_defout.buf + eruby_defout.len, + RSTRING(str)->ptr, RSTRING(str)->len); + eruby_defout.len += RSTRING(str)->len; return Qnil; } static VALUE defout_cancel(VALUE self) { - if (RSTRING(self)->len == 0) return Qnil; - RSTRING(self)->len = 0; - RSTRING(self)->ptr[0] = '\0'; + eruby_defout.len = 0; return Qnil; } +static VALUE defout_new() +{ + eruby_defout.max = 102400; + eruby_defout.len = 0; + eruby_defout.buf = ALLOC_N(char, eruby_defout.max); + return Data_Wrap_Struct(rb_cObject, NULL, NULL, &eruby_defout); +} + +static void defout_free() +{ + free(eruby_defout.buf); +} + + static int guess_mode() { if (getenv("GATEWAY_INTERFACE") == NULL) { @@ -438,7 +464,7 @@ if (eruby_mode == MODE_CGI || eruby_mode == MODE_NPHCGI) rb_set_safe_level(1); - rb_defout = rb_str_new("", 0); + rb_defout = defout_new(); rb_io_binmode(rb_stdout); /* for mswin32 */ rb_define_singleton_method(rb_defout, "write", defout_write, 1); rb_define_singleton_method(rb_defout, "cancel", defout_cancel, 0); @@ -545,8 +571,8 @@ if (eruby_mode == MODE_FILTER && (RTEST(ruby_debug) || RTEST(ruby_verbose))) { print_generated_code(stderr, code, 0); } - out = RSTRING(rb_defout)->ptr; - nout = RSTRING(rb_defout)->len; + out = eruby_defout.buf; + nout = eruby_defout.len; if (!eruby_noheader && (eruby_mode == MODE_CGI || eruby_mode == MODE_NPHCGI)) { if (eruby_mode == MODE_NPHCGI) @@ -558,6 +584,7 @@ } fwrite(out, nout, 1, stdout); fflush(stdout); + defout_free(); } int main(int argc, char **argv) -- ---- - - - -- - うえの かつひろ