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
|
static int
|
||||||
is_integer_p(VALUE v)
|
is_integer_p(VALUE v)
|
||||||
{
|
{
|
||||||
|
if (rb_integer_type_p(v)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ID id_integer_p;
|
ID id_integer_p;
|
||||||
VALUE is_int;
|
VALUE is_int;
|
||||||
CONST_ID(id_integer_p, "integer?");
|
CONST_ID(id_integer_p, "integer?");
|
||||||
@ -2166,17 +2170,22 @@ range_count(int argc, VALUE *argv, VALUE range)
|
|||||||
* Infinity. Just let it loop. */
|
* Infinity. Just let it loop. */
|
||||||
return rb_call_super(argc, argv);
|
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. */
|
/* We are confident that the answer is Infinity. */
|
||||||
return DBL2NUM(HUGE_VAL);
|
return DBL2NUM(HUGE_VAL);
|
||||||
}
|
}
|
||||||
else if (NIL_P(RANGE_BEG(range))) {
|
|
||||||
/* We are confident that the answer is Infinity. */
|
if (is_integer_p(beg)) {
|
||||||
return DBL2NUM(HUGE_VAL);
|
VALUE size = range_size(range);
|
||||||
}
|
if (!NIL_P(size)) {
|
||||||
else {
|
return size;
|
||||||
return rb_call_super(argc, argv);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rb_call_super(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -1075,7 +1075,17 @@ class TestRange < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_count
|
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)
|
||||||
|
assert_equal(Float::INFINITY, (..1).count)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_overlap?
|
def test_overlap?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user