なかだです。

At Fri, 28 Apr 2000 13:57:49 +0900,
matz / netlab.co.jp (Yukihiro Matsumoto) wrote:
> |  Array#unshift は引数は1個です。Array#push はいくつでもいいのに。:-P
> 
> そうですね。パッチも頂いたことだし、1.5.xでは複数にしましょ
> うか。

  あれだと一つずつ MEMMOVE() していくことになって、効率が少々気
になるので、一気に持ってくようにしてみました。ついでに push と
concat の方も、大量にやったときに RALLOC() の回数が減るかもとい
うことで。なんとなくシンメトリカル。


Index: array.c =================================================================== RCS file: /home/cvs/ruby/array.c,v retrieving revision 1.17 diff -u -2 -p -r1.17 array.c --- array.c 2000/04/10 05:44:05 1.17 +++ array.c 2000/04/29 04:58:12 @@ -277,6 +277,13 @@ rb_ary_push_m(argc, argv, ary) VALUE ary; { - while (argc--) { - rb_ary_store(ary, RARRAY(ary)->len, *argv++); + if (argc > 0) { + long len = RARRAY(ary)->len; + + --argc; + /* make rooms by copying the last item */ + rb_ary_store(ary, len + argc, argv[argc]); + + if (argc) /* if any rest */ + MEMCPY(RARRAY(ary)->ptr + len, argv, VALUE, argc); } return ary; @@ -341,4 +348,24 @@ rb_ary_unshift(ary, item) } +static VALUE +rb_ary_unshift_m(argc, argv, ary) + int argc; + VALUE *argv; + VALUE ary; +{ + if (argc > 0) { + long len = RARRAY(ary)->len; + + /* make rooms by setting the last item */ + rb_ary_store(ary, len + argc - 1, Qnil); + + /* sliding items */ + MEMMOVE(RARRAY(ary)->ptr + argc, RARRAY(ary)->ptr, VALUE, len); + + MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc); + } + return ary; +} + VALUE rb_ary_entry(ary, offset) @@ -1196,15 +1223,7 @@ rb_ary_concat(x, y) VALUE x, y; { - VALUE *p, *pend; - - rb_ary_modify(x); Check_Type(y, T_ARRAY); - p = RARRAY(y)->ptr; - pend = p + RARRAY(y)->len; - while (p < pend) { - rb_ary_store(x, RARRAY(x)->len, *p); - p++; - } + rb_ary_push_m(RARRAY(y)->len, RARRAY(y)->ptr, x); return x; } @@ -1576,5 +1595,5 @@ Init_Array() rb_define_method(rb_cArray, "pop", rb_ary_pop, 0); rb_define_method(rb_cArray, "shift", rb_ary_shift, 0); - rb_define_method(rb_cArray, "unshift", rb_ary_unshift, 1); + rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1); rb_define_method(rb_cArray, "each", rb_ary_each, 0); rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
Sat Apr 29 13:38:00 2000 Nobuyoshi Nakada <nobu.nakada / nifty.ne.jp> * array.c (rb_ary_push_m): making rooms by rb_ary_store() once and copys with MEMCOPY(). * array.c (rb_ary_unshift_m): newly added to allow multiple items. * array.c (rb_ary_concat): equivalents to `push(*ary)'. * array.c (Init_Array): changed Array#unshift implementation to allow multiple items.
-- そうだ 強気に ちょっと インチキに☆彡 中田 "Bugるくらいがちょうどいいかも;-)" 伸悦