8000 Move Array#map to Ruby · ruby/ruby@b974c84 · GitHub
[go: up one dir, main page]

Skip to content

Commit b974c84

Browse files
committed
Move Array#map to Ruby
Improves activerecord by about 1% on the interpreter: ``` before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b) [arm64-darwin23] after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4e) [arm64-darwin23] ------------ ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after activerecord 235.2 0.8 233.6 0.7 1.01 1.01 ------------ ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. ``` Improves YJIT by about 4%: ``` before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b) +YJIT [arm64-darwin23] after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4e) +YJIT [arm64-darwin23] ------------ ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after activerecord 142.1 1.2 137.0 0.6 1.00 1.04 ------------ ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. ```
1 parent 6ac05dd commit b974c84

File tree

4 files changed

+44
-45
lines changed

4 files changed

+44
-45
lines changed

array.c

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3630,41 +3630,6 @@ rb_ary_sort_by_bang(VALUE ary)
36303630
return ary;
36313631
}
36323632

3633-
3634-
/*
3635-
* call-seq:
3636-
* array.map {|element| ... } -> new_array
3637-
* array.map -> new_enumerator
3638-
*
3639-
* Calls the block, if given, with each element of +self+;
3640-
* returns a new +Array+ whose elements are the return values from the block:
3641-
*
3642-
* a = [:foo, 'bar', 2]
3643-
* a1 = a.map {|element| element.class }
3644-
* a1 # => [Symbol, String, Integer]
3645-
*
3646-
* Returns a new Enumerator if no block given:
3647-
* a = [:foo, 'bar', 2]
3648-
* a1 = a.map
3649-
* a1 # => #<Enumerator: [:foo, "bar", 2]:map>
3650-
*
3651-
*/
3652-
3653-
static VALUE
3654-
rb_ary_collect(VALUE ary)
3655-
{
3656-
long i;
3657-
VALUE collect;
3658-
3659-
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3660-
collect = rb_ary_new2(RARRAY_LEN(ary));
3661-
for (i = 0; i < RARRAY_LEN(ary); i++) {
3662-
rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
3663-
}
3664-
return collect;
3665-
}
3666-
3667-
36683633
/*
36693634
* call-seq:
36703635
* array.map! {|element| ... } -> self
@@ -8668,9 +8633,7 @@ Init_Array(void)
86688633
rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
86698634
rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0);
86708635
rb_define_method(rb_cArray, "sort_by!", rb_ary_sort_by_bang, 0);
8671-
rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
86728636
rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0);
8673-
rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
86748637
rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
86758638
rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0);
86768639
rb_define_method(rb_cArray, "filter!", rb_ary_select_bang, 0);

array.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,40 @@ def each
5656
self
5757
end
5858

59+
# call-seq:
60+
# array.map {|element| ... } -> new_array
61+
# array.map -> new_enumerator
62+
#
63+
# Calls the block, if given, with each element of +self+;
64+
# returns a new +Array+ whose elements are the return values from the block:
65+
#
66+
# a = [:foo, 'bar', 2]
67+
# a1 = a.map {|element| element.class }
68+
# a1 # => [Symbol, String, Integer]
69+
#
70+
# Returns a new Enumerator if no block given:
71+
# a = [:foo, 'bar', 2]
72+
# a1 = a.map
73+
# a1 # => #<Enumerator: [:foo, "bar", 2]:map>
74+
def map
75+
Primitive.attr! :inline_block
76+
Primitive.attr! :use_block
77+
78+
unless defined?(yield)
79+
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, ary_enum_length)'
80+
end
81+
82+
_i = 0
83+
value = nil
84+
result = Primitive.ary_sized_alloc
85+
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
86+
result << yield(value)
87+
end
88+
result
89+
end
90+
91+
alias collect map
92+
5993
# call-seq:
6094
# array.select {|element| ... } -> new_array
6195
# array.select -> new_enumerator

test/ruby/test_backtrace.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,15 @@ def self.foo
223223
@res = caller_locations(2, 1).inspect
224224
end
225225
@line = __LINE__ + 1
226-
[1].map.map { [1].map.map { foo } }
227-
assert_equal("[\"#{__FILE__}:#{@line}:in 'Array#map'\"]", @res)
226+
[1].map!.map { [1].map!.map { foo } }
227+
assert_equal("[\"#{__FILE__}:#{@line}:in 'Array#map!'\"]", @res)
228228
end
229229

230230
def test_caller_location_path_cfunc_iseq_no_pc
231231
def self.foo
232232
@res = caller_locations(2, 1)[0].path
233233
end
234-
[1].map.map { [1].map.map { foo } }
234+
[1].map!.map { [1].map!.map { foo } }
235235
assert_equal(__FILE__, @res)
236236
end
237237

test/ruby/test_settracefunc.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -680,10 +680,8 @@ def trace_by_set_trace_func
680680
#
681681
[:c_return, 1, "xyzzy", TracePoint, :trace, TracePoint, nil, nil],
682682
[:line, 4, 'xyzzy', self.class, method, self, :outer, :nothing],
683-
[:c_call, 4, 'xyzzy', Integer, :times, 1, nil, nil],
684683
[:line, 4, 'xyzzy', self.class, method, self, nil, :nothing],
685684
[:line, 5, 'xyzzy', self.class, method, self, :inner, :nothing],
686-
[:c_return, 4, "xyzzy", Integer, :times, 1, nil, nil],
687685
[:line, 7, 'xyzzy', self.class, method, self, :outer, :nothing],
688686
[:c_call, 7, "xyzzy", Class, :inherited, Object, nil, nil],
689687
[:c_return, 7, "xyzzy", Class, :inherited, Object, nil, nil],
@@ -1069,10 +1067,12 @@ def test_tracepoint_block
10691067
# pp events
10701068
# expected_events =
10711069
[[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
1072-
[:c_call, :map, Array, Array, nil],
1070+
[:call, :map, Array, Array, nil],
10731071
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
10741072
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 3],
1075-
[:c_return, :map, Array, Array, [3]],
1073+
[:c_call, :<<, Array, Array, nil],
1074+
[:c_return, :<<, Array, Array, [3]],
1075+
[:return, :map, Array, Array, [3]],
10761076
[:call, :method_for_test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
10771077
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
10781078
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 4],
@@ -1386,8 +1386,9 @@ def test_a_call
13861386
}
13871387
assert_equal([
13881388
:b_call,
1389-
:c_call,
1389+
:call,
13901390
:b_call,
1391+
:c_call,
13911392
:call,
13921393
:b_call,
13931394
], events)
@@ -1409,6 +1410,7 @@ def test_a_return
14091410
assert_equal([
14101411
:b_return,
14111412
:c_return,
1413+
:return,
14121414
:b_return,
14131415
:return,
14141416
:b_return

0 commit comments

Comments
 (0)
0