for some time I’m wondering if there exists a library with datastructures
like deque, queue, list, btree, and similar in ruby, such that I don’t
have to implement them myself?
Until now I have found nothing, so I’m posting here in the hope that I
should not have re-rtfm’d more.
for some time I’m wondering if there exists a library with datastructures
like deque, queue, list, btree, and similar in ruby, such that I don’t
have to implement them myself?
deque, queue, list… then ruby’s builtin Array class will fit.
“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:20040520123256.46e2f1c3.neoneye@adslhome.dk…
for some time I’m wondering if there exists a library with
datastructures
like deque, queue, list, btree, and similar in ruby, such that I don’t
have to implement them myself?
deque, queue, list… then ruby’s builtin Array class will fit.
Thanks for your answer. I should have looked in the raa by myself. Just a
question regarding array as deque. How efficient is it? Is all the data
shifted through the array every time I push something at the front and
remove it from the back, or is it organized more efficiently?
Thanks,
Brian
···
On Thu, 20 May 2004 19:37:19 +0900, Simon Strandgaard wrote:
deque, queue, list… then ruby’s builtin Array class will fit.
Thanks for your answer. I should have looked in the raa by myself. Just a
question regarding array as deque. How efficient is it? Is all the data
shifted through the array every time I push something at the front and
remove it from the back, or is it organized more efficiently?
I don’t know how Array is implemented… I think matz (Ruby’s author) has
chosen a datastructure with constant-time head/tail insert/removal.
Not sure though.
It would be nice with an O(x) chart of the most common operations:
my guess … please correct me if im wrong
···
push element O(1)
pop element O(1)
shift element O(?) I hope O(1)
unshift element O(?) I hope O(1)
insert element O(n)
remove element O(n)
…
Thanks for your answer. I should have looked in the raa by myself. Just a
question regarding array as deque. How efficient is it? Is all the data
shifted through the array every time I push something at the front and
remove it from the back, or is it organized more efficiently?
If I’m not mistaken, #push (appends at the end), #pop (remove last) and #shift (remove first) are efficient (#shift moves the pointer). #unshift
(insert at beginning) moves all elements.
Interpretation: it looks like unshift is slightly (~6%) slower than
pop. shift is barely faster than push. Still, they are all comparable
in speed.
I ran this test a few times, with similar results.
cheers,
–Mark
···
On May 20, 2004, at 5:23 AM, Brian Schroeder wrote:
Thanks for your answer. I should have looked in the raa by myself.
Just a
question regarding array as deque. How efficient is it? Is all the data
shifted through the array every time I push something at the front and
remove it from the back, or is it organized more efficiently?
I don’t know how Array is implemented… I think matz (Ruby’s author) has
chosen a datastructure with constant-time head/tail insert/removal.
Not sure though.
It would be nice with an O(x) chart of the most common operations:
my guess … please correct me if im wrong
push element O(1)
pop element O(1)
shift element O(?) I hope O(1)
unshift element O(?) I hope O(1)
insert element O(n)
remove element O(n)
…
–
Simon Strandgaard
Assuming that the Array is set up like a C/C++ (double) linked list
with pointers, then all should take Theta(1), except insert which can
take Theta(n) if the element is out of the Array boundary and all
intermediate items need to be created first. If insert/remove
specifies inserting elements into a sorted list then it can be done in
Theta(log n) by using a binary search to find the location to insert.
On May 20, 2004, at 5:23 AM, Brian Schroeder wrote:
Thanks for your answer. I should have looked in the raa by myself.
Just a
question regarding array as deque. How efficient is it? Is all the data
shifted through the array every time I push something at the front and
remove it from the back, or is it organized more efficiently?
One of the great things about ruby is how easy it is to test things
like this
mark@imac% ruby
require ‘profile’
def t_pop(ary) 5000.times{|n| ary.pop} end
def t_push(ary) 5000.times{|n| ary.push n} end
def t_shift(ary) 5000.times{|n| ary.shift} end
def t_unshift(ary) 5000.times{|n| ary.unshift n} end
How much does it cost for an array access in the middle? Why does it cost
order(n) to remove the tail? Why doesn’t it float backwards until it needs
memory ahead of it for instance? I’d be curious to now a bit more of about
this, as well as how the other datastructures are implemented.
Charlie
···
On Thu, 20 May 2004, Mauricio Fernández wrote:
On Thu, May 20, 2004 at 09:45:12PM +0900, Simon Strandgaard wrote:
my guess … please correct me if im wrong
push element O(1)
amortized O(1), I think
pop element O(1)
shift element O(?) I hope O(1)
O(1)
unshift element O(?) I hope O(1)
O(n)
insert element O(n)
remove element O(n)
…
How much does it cost for an array access in the middle?
O(1), since an Array is implemented as a C array of VALUEs.
Why does it cost order(n) to remove the tail? Why doesn’t it float
backwards until it needs memory ahead of it for instance?
Array uses internally an array of VALUEs, array->ptr.
When you unshift a VALUE, it has to be inserted at array->ptr[0]; all
elements must be shifted, hence O(n). You cannot just do array->ptr–
since you’d fall outside the malloc()ed area.
I’d be curious to now a bit more of about
this, as well as how the other datastructures are implemented.
I recommend you read the sources, they are very easy to follow. For
instance, to see how unshift is implemented, just look at array.c, and
scroll down to the method definition to find the associated C function.
rb_define_method(rb_cArray, “unshift”, rb_ary_unshift_m, -1);
···
On Fri, May 21, 2004 at 07:23:47AM +0900, Charles Comstock wrote:
================
–
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com