rb_ary_sum: don't enter fast path if initial isn't a native numeric type.
[Bug #19530] If the initial value isn't one of the special cased types, we directly jump to the slow path.
This commit is contained in:
parent
6462c1a042
commit
ca437aeb39
Notes:
git
2023-03-15 09:13:22 +00:00
7
array.c
7
array.c
@ -8181,6 +8181,12 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
|
|||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
r = Qundef;
|
r = Qundef;
|
||||||
|
|
||||||
|
if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {
|
||||||
|
i = 0;
|
||||||
|
goto init_is_a_value;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||||
e = RARRAY_AREF(ary, i);
|
e = RARRAY_AREF(ary, i);
|
||||||
if (block_given)
|
if (block_given)
|
||||||
@ -8265,6 +8271,7 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
|
|||||||
}
|
}
|
||||||
|
|
||||||
goto has_some_value;
|
goto has_some_value;
|
||||||
|
init_is_a_value:
|
||||||
for (; i < RARRAY_LEN(ary); i++) {
|
for (; i < RARRAY_LEN(ary); i++) {
|
||||||
e = RARRAY_AREF(ary, i);
|
e = RARRAY_AREF(ary, i);
|
||||||
if (block_given)
|
if (block_given)
|
||||||
|
@ -10,6 +10,10 @@ describe "Array#sum" do
|
|||||||
[1, 2, 3].sum { |i| i * 10 }.should == 60
|
[1, 2, 3].sum { |i| i * 10 }.should == 60
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "doesn't apply the block init" do
|
||||||
|
[1, 2, 3].sum(1) { |i| i * 10 }.should == 61
|
||||||
|
end
|
||||||
|
|
||||||
# https://bugs.ruby-lang.org/issues/12217
|
# https://bugs.ruby-lang.org/issues/12217
|
||||||
# https://github.com/ruby/ruby/blob/master/doc/ChangeLog/ChangeLog-2.4.0#L6208-L6214
|
# https://github.com/ruby/ruby/blob/master/doc/ChangeLog/ChangeLog-2.4.0#L6208-L6214
|
||||||
it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do
|
it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do
|
||||||
@ -69,6 +73,15 @@ describe "Array#sum" do
|
|||||||
a.should_receive(:+).with(b).and_return(42)
|
a.should_receive(:+).with(b).and_return(42)
|
||||||
[b].sum(a).should == 42
|
[b].sum(a).should == 42
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ruby_bug '#19530', ''...'3.3' do
|
||||||
|
it "calls + on the init value" do
|
||||||
|
a = mock("a")
|
||||||
|
b = mock("b")
|
||||||
|
a.should_receive(:+).with(42).and_return(b)
|
||||||
|
[42].sum(a).should == b
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Array#sum" do
|
describe "Array#sum" do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user