ruby-changes:3943
From: ko1@a...
Date: Tue, 12 Feb 2008 02:47:14 +0900 (JST)
Subject: [ruby-changes:3943] matz - Ruby:r15433 (trunk): * range.c (range_include): specialize single character string
matz 2008-02-12 02:46:52 +0900 (Tue, 12 Feb 2008) New Revision: 15433 Modified files: trunk/ChangeLog trunk/object.c trunk/parse.y trunk/range.c trunk/string.c trunk/version.h Log: * range.c (range_include): specialize single character string case (e.g. (?a ..?z).include(?x)) for performance. [ruby-core:15481] * string.c (rb_str_upto): specialize single character case. * string.c (rb_str_hash): omit coderange scan for performance. * object.c (rb_check_to_integer): check Fixnum first. * object.c (rb_to_integer): ditto. * string.c (rb_str_equal): inline memcmp to avoid unnecessary rb_str_comparable(). * parse.y (rb_intern2): use US-ASCII encoding. * parse.y (rb_intern_str): ditto. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/version.h?r1=15433&r2=15432&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/string.c?r1=15433&r2=15432&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/parse.y?r1=15433&r2=15432&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15433&r2=15432&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/range.c?r1=15433&r2=15432&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/object.c?r1=15433&r2=15432&diff_format=u Index: ChangeLog =================================================================== --- ChangeLog (revision 15432) +++ ChangeLog (revision 15433) @@ -1,3 +1,24 @@ +Tue Feb 12 02:42:27 2008 Yukihiro Matsumoto <matz@r...> + + * range.c (range_include): specialize single character string + case (e.g. (?a ..?z).include(?x)) for performance. + [ruby-core:15481] + + * string.c (rb_str_upto): specialize single character case. + + * string.c (rb_str_hash): omit coderange scan for performance. + + * object.c (rb_check_to_integer): check Fixnum first. + + * object.c (rb_to_integer): ditto. + + * string.c (rb_str_equal): inline memcmp to avoid unnecessary + rb_str_comparable(). + + * parse.y (rb_intern2): use US-ASCII encoding. + + * parse.y (rb_intern_str): ditto. + Mon Feb 11 17:21:18 2008 Kouhei Sutou <kou@c...> * lib/rss/rss.rb (RSS::VERSION), test/rss/test_version.rb: Index: string.c =================================================================== --- string.c (revision 15432) +++ string.c (revision 15433) @@ -1509,11 +1509,7 @@ int rb_str_hash(VALUE str) { - int e = ENCODING_GET(str); - if (e && is_ascii_string(str)) { - e = 0; - } - return hash((const void *)RSTRING_PTR(str), RSTRING_LEN(str), e); + return hash((const void *)RSTRING_PTR(str), RSTRING_LEN(str), 0); } /* @@ -1593,6 +1589,8 @@ VALUE rb_str_equal(VALUE str1, VALUE str2) { + int len; + if (str1 == str2) return Qtrue; if (TYPE(str2) != T_STRING) { if (!rb_respond_to(str2, rb_intern("to_str"))) { @@ -1601,8 +1599,8 @@ return rb_equal(str2, str1); } if (!rb_str_comparable(str1, str2)) return Qfalse; - if (RSTRING_LEN(str1) == RSTRING_LEN(str2) && - rb_str_cmp(str1, str2) == 0) { + if (RSTRING_LEN(str1) == (len = RSTRING_LEN(str2)) && + memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len) == 0) { return Qtrue; } return Qfalse; @@ -2295,14 +2293,30 @@ VALUE current, after_end; ID succ; int n, excl; + rb_encoding *enc; rb_scan_args(argc, argv, "11", &end, &exclusive); - rb_enc_check(beg, end); excl = RTEST(exclusive); succ = rb_intern("succ"); StringValue(end); + enc = rb_enc_check(beg, end); + if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1 && + is_ascii_string(beg) && is_ascii_string(end)) { + char c = RSTRING_PTR(beg)[0]; + char e = RSTRING_PTR(end)[0]; + + if (c > e || (excl && c == e)) return beg; + for (;;) { + rb_yield(rb_enc_str_new(&c, 1, enc)); + if (!excl && c == e) break; + c++; + if (excl && c == e) break; + } + return beg; + } n = rb_str_cmp(beg, end); if (n > 0 || (excl && n == 0)) return beg; + after_end = rb_funcall(end, succ, 0, 0); current = beg; while (!rb_str_equal(current, after_end)) { @@ -2311,7 +2325,6 @@ current = rb_funcall(current, succ, 0, 0); StringValue(current); if (excl && rb_str_equal(current, end)) break; - StringValue(current); if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0) break; } Index: object.c =================================================================== --- object.c (revision 15432) +++ object.c (revision 15433) @@ -1940,7 +1940,10 @@ static VALUE rb_to_integer(VALUE val, const char *method) { - VALUE v = convert_type(val, "Integer", method, Qtrue); + VALUE v; + + if (FIXNUM_P(val)) return val; + v = convert_type(val, "Integer", method, Qtrue); if (!rb_obj_is_kind_of(v, rb_cInteger)) { char *cname = rb_obj_classname(val); rb_raise(rb_eTypeError, "can't convert %s to Integer (%s#%s gives %s)", @@ -1952,7 +1955,10 @@ VALUE rb_check_to_integer(VALUE val, const char *method) { - VALUE v = convert_type(val, "Integer", method, Qfalse); + VALUE v; + + if (FIXNUM_P(val)) return val; + v = convert_type(val, "Integer", method, Qfalse); if (!rb_obj_is_kind_of(v, rb_cInteger)) { return Qnil; } Index: range.c =================================================================== --- range.c (revision 15432) +++ range.c (revision 15433) @@ -10,6 +10,7 @@ **********************************************************************/ #include "ruby/ruby.h" +#include "ruby/encoding.h" VALUE rb_cRange; static ID id_cmp, id_succ, id_beg, id_end, id_excl; @@ -748,6 +749,27 @@ } return Qfalse; } + else if (TYPE(beg) == T_STRING && TYPE(end) == T_STRING && + RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1) { + rb_encoding *enc = rb_enc_check(beg, end); + + if (NIL_P(val)) return Qfalse; + if (TYPE(val) == T_STRING) { + if (RSTRING_LEN(val) == 0 || RSTRING_LEN(val) > 1) + return Qfalse; + else { + char b = RSTRING_PTR(beg)[0]; + char e = RSTRING_PTR(end)[0]; + char v = RSTRING_PTR(val)[0]; + + if (ISASCII(b) && ISASCII(e) && ISASCII(v)) { + if (b <= v && v < e) return Qtrue; + if (!EXCL(range) && v == e) return Qtrue; + return Qfalse; + } + } + } + } /* TODO: ruby_frame->this_func = rb_intern("include?"); */ return rb_call_super(1, &val); } Index: parse.y =================================================================== --- parse.y (revision 15432) +++ parse.y (revision 15433) @@ -271,7 +271,7 @@ #define STR_NEW0() rb_enc_str_new(0,0,rb_usascii_encoding()) #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),parser->enc) #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),parser->enc) -#define STR_ENC(m) ((m)?parser->enc:rb_ascii8bit_encoding()) +#define STR_ENC(m) ((m)?parser->enc:rb_usascii_encoding()) #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT) #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), STR_ENC(mb)) @@ -9043,7 +9043,7 @@ ID rb_intern2(const char *name, long len) { - return rb_intern3(name, len, rb_ascii8bit_encoding()); + return rb_intern3(name, len, rb_usascii_encoding()); } #undef rb_intern @@ -9056,14 +9056,16 @@ ID rb_intern_str(VALUE str) { - int idx = 0; + rb_encoding *enc; ID id; - if (rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) { - idx = rb_enc_get_index(str); + if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) { + enc = rb_usascii_encoding(); } - id = rb_intern3(RSTRING_PTR(str), RSTRING_LEN(str), - rb_enc_from_index(idx)); + else { + enc = rb_enc_get(str); + } + id = rb_intern3(RSTRING_PTR(str), RSTRING_LEN(str), enc); RB_GC_GUARD(str); return id; } Index: version.h =================================================================== --- version.h (revision 15432) +++ version.h (revision 15433) @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2008-02-11" +#define RUBY_RELEASE_DATE "2008-02-12" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20080211 +#define RUBY_RELEASE_CODE 20080212 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 2 -#define RUBY_RELEASE_DAY 11 +#define RUBY_RELEASE_DAY 12 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/