Optimize Range#count
by using range_size
if possible
This commit is contained in:
parent
e0c66b4749
commit
6ae2996e29
11
benchmark/range_count.yml
Normal file
11
benchmark/range_count.yml
Normal file
@ -0,0 +1,11 @@
|
||||
prelude: |
|
||||
r_1 = 1..1
|
||||
r_1k = 1..1000
|
||||
r_1m = 1..1000000
|
||||
r_str = 'a'..'z'
|
||||
|
||||
benchmark:
|
||||
'int 1': r_1.count
|
||||
'int 1K': r_1k.count
|
||||
'int 1M': r_1m.count
|
||||
string: r_str.count
|
23
range.c
23
range.c
@ -607,6 +607,10 @@ double_as_int64(double d)
|
||||
static int
|
||||
is_integer_p(VALUE v)
|
||||
{
|
||||
if (rb_integer_type_p(v)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ID id_integer_p;
|
||||
VALUE is_int;
|
||||
CONST_ID(id_integer_p, "integer?");
|
||||
@ -2166,17 +2170,22 @@ range_count(int argc, VALUE *argv, VALUE range)
|
||||
* Infinity. Just let it loop. */
|
||||
return rb_call_super(argc, argv);
|
||||
}
|
||||
else if (NIL_P(RANGE_END(range))) {
|
||||
|
||||
VALUE beg = RANGE_BEG(range), end = RANGE_END(range);
|
||||
|
||||
if (NIL_P(beg) || NIL_P(end)) {
|
||||
/* We are confident that the answer is Infinity. */
|
||||
return DBL2NUM(HUGE_VAL);
|
||||
}
|
||||
else if (NIL_P(RANGE_BEG(range))) {
|
||||
/* We are confident that the answer is Infinity. */
|
||||
return DBL2NUM(HUGE_VAL);
|
||||
}
|
||||
else {
|
||||
return rb_call_super(argc, argv);
|
||||
|
||||
if (is_integer_p(beg)) {
|
||||
VALUE size = range_size(range);
|
||||
if (!NIL_P(size)) {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
return rb_call_super(argc, argv);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1075,7 +1075,17 @@ class TestRange < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_count
|
||||
assert_equal 42, (1..42).count
|
||||
assert_equal 41, (1...42).count
|
||||
assert_equal 0, (42..1).count
|
||||
assert_equal 0, (42...1).count
|
||||
assert_equal 2**100, (1..2**100).count
|
||||
assert_equal 6, (1...6.3).count
|
||||
assert_equal 4, ('a'..'d').count
|
||||
assert_equal 3, ('a'...'d').count
|
||||
|
||||
assert_equal(Float::INFINITY, (1..).count)
|
||||
assert_equal(Float::INFINITY, (..1).count)
|
||||
end
|
||||
|
||||
def test_overlap?
|
||||
|
Loading…
x
Reference in New Issue
Block a user