Project

General

Profile

Actions

Bug #1650

closed

Time range === is slow

Added by kmeaw (Dmitry Bilunov) almost 15 years ago. Updated almost 13 years ago.

Status:
Rejected
Target version:
ruby -v:
ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]
Backport:
[ruby-core:23908]

Description

=begin
The following program runs N times slower in ruby19 compared to ruby18.
N depends on the input range size.

dev@rails ~ $ time ruby19 -rtime -e '(Time.now - 1000000 .. Time.now) === (Time.now - 3)'

real 0m0.723s
user 0m0.709s
sys 0m0.013s
dev@rails ~ $ time ruby18 -rtime -e '(Time.now - 1000000 .. Time.now) === (Time.now - 3)'

real 0m0.043s
user 0m0.039s
sys 0m0.005s
=end

Actions #1

Updated by drbrain (Eric Hodel) almost 15 years ago

=begin
Adding Time#to_int allows Range#include? to use its fast path, but I don't know if it is appropriate. There's a Process::Status#to_int so I suppose it would be valid for Time too.
=end

Actions #2

Updated by matz (Yukihiro Matsumoto) almost 15 years ago

=begin
Hi,

In message "Re: [ruby-core:23908] [Bug #1650] Time range === is slow"
on Thu, 18 Jun 2009 09:48:30 +0900, Dmitry Bilunov writes:

|The following program runs N times slower in ruby19 compared to ruby18.
|N depends on the input range size.

1.9 Range#=== now checks according to enumeration (unless both ends
are integers). It might be improved in the future, but until then, I
recommend you to use t3.between?(t1, t2) instead of (t1 .. t2)===t3.

						matz.

=end

Actions #3

Updated by yugui (Yuki Sonoda) almost 15 years ago

  • Status changed from Open to Rejected

=begin

=end

Actions #4

Updated by cdunn2001 (Christopher Dunn) over 13 years ago

=begin
That's not what the docs say. They are ambiguous. http://ruby-doc.org/ruby-1.9/classes/Range.html:

  • rng.cover?(val) => true or false
    Returns true if obj is between beg and end, i.e beg <= obj <= end (or end exclusive when exclude_end? is true).

  • rng.include?(val) => true or false
    Returns true if obj is an element of rng, false otherwise. If beg and end are numeric, comparison is done according magnitude of values.

  • rng === obj => true or false
    Returns true if obj is an element of rng, false otherwise. Conveniently, === is the comparison operator used by case statements.

If Range#=== works exactly the same as Range#include?, the docs should say that. If they differ when beg/end are numeric, the docs should say that. I really do not know precisely how Range#=== works from the docs, the web, or this discussion. I have to test it myself. The distinction is critical because it may dramatically impact performance of 'case' statements in the move from 1.8 to 1.9.

Please update the docs with clarification.
=end

Actions #5

Updated by marcandre (Marc-Andre Lafortune) over 13 years ago

  • Category changed from lib to doc
  • Status changed from Rejected to Open

=begin

=end

Updated by naruse (Yui NARUSE) almost 13 years ago

  • Status changed from Open to Assigned
  • Assignee set to akr (Akira Tanaka)

Updated by nahi (Hiroshi Nakamura) almost 13 years ago

  • Target version set to 1.9.3

Updated by neleai (Ondrej Bilka) almost 13 years ago

Ah bug I pointed out in ruby-core:8609
currently there is following error.
-:1:in each': can't iterate from Time (TypeError) from -:1:in include?'
from -:1:in include?' from -:1:in ==='
from -:1:in `'

Anyway what is worse (Time.now - 1000000 .. Time.now) === (Time.now - 3)
returns false as it enumerates Times and third time is usualy few
microseconds off.

To me === expected behaviour is that (a..b)===c should call c.between?(a,b).

Problem at this time was that matz wanted in 1.9 ("a1".."a11") === "a9"
return true (which in 1.8 returns false.
This also could be slow for example for ("a1".."a1000000000") === "ab"

My proposal was call between and redefine String#between to do desired
comparison as in patch attached at ruby-core:8609
BTW patch is more general than one-char comparsion as is in
range_include

On Sun, Jun 26, 2011 at 04:43:06PM +0900, Hiroshi NAKAMURA wrote:

Issue #1650 has been updated by Hiroshi NAKAMURA.

Target version set to 1.9.3


Bug #1650: Time range === is slow
http://redmine.ruby-lang.org/issues/1650

Author: Dmitry Bilunov
Status: Assigned
Priority: Normal
Assignee: Akira Tanaka
Category: DOC
Target version: 1.9.3
ruby -v: ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]

=begin
The following program runs N times slower in ruby19 compared to ruby18.
N depends on the input range size.

dev@rails ~ $ time ruby19 -rtime -e '(Time.now - 1000000 .. Time.now) === (Time.now - 3)'

real 0m0.723s
user 0m0.709s
sys 0m0.013s
dev@rails ~ $ time ruby18 -rtime -e '(Time.now - 1000000 .. Time.now) === (Time.now - 3)'

real 0m0.043s
user 0m0.039s
sys 0m0.005s
=end

--
http://redmine.ruby-lang.org

--

Network failure - call NBC

Updated by mame (Yusuke Endoh) almost 13 years ago

  • Status changed from Assigned to Rejected

Hello,

If Range#=== works exactly the same as Range#include?, the docs should say that. If they differ when beg/end are numeric, the docs should say that.

That is an implementation detail, I think. Not a bug. So I'm closing
the ticket.
If you want to clarify it as a spec, please register another ticket
into feature tracker.

Thank you,

--
Yusuke Endoh

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0