[#5322] O(1) performance for insertions/deletions at the front of an Array/String — Eric Mahurin <eric_mahurin@...>

I just did some benchmarks on push, pop, shift, and unshift

24 messages 2005/07/01
[#5338] Re: O(1) performance for insertions/deletions at the front of an Array/String — Mathieu Bouchard <matju@...> 2005/07/02

On Fri, 1 Jul 2005, Eric Mahurin wrote:

[#5348] Re: O(1) performance for insertions/deletions at the front of an Array/String — Eric Mahurin <eric_mahurin@...> 2005/07/02

--- Mathieu Bouchard <matju@artengine.ca> wrote:

[#5357] Re: O(1) performance for insertions/deletions at the front of an Array/String — Mathieu Bouchard <matju@...> 2005/07/03

On Sat, 2 Jul 2005, Eric Mahurin wrote:

[#5359] Re: O(1) performance for insertions/deletions at the front of an Array/String — Eric Mahurin <eric_mahurin@...> 2005/07/03

--- Mathieu Bouchard <matju@artengine.ca> wrote:

[#5361] Re: O(1) performance for insertions/deletions at the front of an Array/String — Mathieu Bouchard <matju@...> 2005/07/03

On Sun, 3 Jul 2005, Eric Mahurin wrote:

[#5362] Re: O(1) performance for insertions/deletions at the front of an Array/String — Eric Mahurin <eric_mahurin@...> 2005/07/03

--- Mathieu Bouchard <matju@artengine.ca> wrote:

[#5365] Re: O(1) performance for insertions/deletions at the front of an Array/String — Yukihiro Matsumoto <matz@...> 2005/07/04

Hi,

[#5367] Re: O(1) performance for insertions/deletions at the front of an Array/String — Eric Mahurin <eric_mahurin@...> 2005/07/04

--- Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

[#5368] Re: O(1) performance for insertions/deletions at the front of an Array/String — Yukihiro Matsumoto <matz@...> 2005/07/04

Hi,

[#5372] Re: O(1) performance for insertions/deletions at the front of an Array/String — Florian Gro<florgro@...> 2005/07/04

Yukihiro Matsumoto wrote:

[#5420] Sydney Developer Preview 1 released — Evan Webb <evanwebb@...>

Sydney, an experimental ruby interpreter, has been released!

15 messages 2005/07/11
[#5424] Re: [ANN] Sydney Developer Preview 1 released — Evan Webb <evanwebb@...> 2005/07/12

Thanks everyone for the feedback so far!

O(1) performance for insertions/deletions at the front of an Array/String

From: Eric Mahurin <eric_mahurin@...>
Date: 2005-07-01 14:59:25 UTC
List: ruby-core #5322
I just did some benchmarks on push, pop, shift, and unshift
and/or various equivalents for both the Array and String
classes.  I was using 100000 elements.  Here are my findings:

1. push/pop and equivalents have O(1) performance as expected.

2. shift also has O(1) performance.  I'm assuming that it
simply moves the start of array pointer by 1 instead of
shifting the data.

3. unshift has O(1) performance when you unshift no more than
the amount you have shifted.  I'd assume it just decremented
the start of array pointer.  When you unshift more than you
shifted, it is O(n), physically moving the data to the right.

4. all other equivalents to shift and unshift (slice!(0),
delete_at(0), insert(0,), [0,]=) have O(n) performance.

I have a couple applications where being able to quickly
insert/delete at the front and back of an Array/String would be
great.

Here are my suggestions to you core developers (the ones
responsible for Array/String at least):

a. at least make equivalents to shift (slice!(0), slice!(0,n)
delete_at(0), [0,n]=nil/[]/"") also O(1).  In the String class
there is currently no fast equivalent to Array#shift.

b. make unshift (and equivalents in Array and String) always
O(1).  This could be done my stretching the Array/String to the
left just like push (and equivalents) stretches the
Array/String to the right in memory.

c. if shifts/unshifts can be made just as fast as pushes/pops,
you could cut the average time in half for random insertions
and deletions.  You could insert/delete toward the closest end
of the Array/String and on average move half the amount of
data.  The closer you are to either end, the less data that
needs to be moved.

For reference, here is a ruby implementation showing how all 4
insert/delete operations at the ends can be made O(1).  This
was pretty easy since shift is O(1).  It would be a little more
difficult to implement this for a String right now.

class Array2
    def initialize(after=[],before=[])
        @after = after
        @before = before
    end
    def push(*args)
        @after.push(*args)
    end
    def pop
        v = @after.pop
        v.nil? && @after.empty? && (v = @before.shift)
        v
    end
    def unshift(*args)
        @before.push(*(args.reverse))
    end
    def shift
        v = @before.pop
        v.nil? && @before.empty? && (v = @after.shift)
        v
    end
end




		
__________________________________ 
Yahoo! Mail 
Stay connected, organized, and protected. Take the tour: 
http://tour.mail.yahoo.com/mailtour.html 


In This Thread

Prev Next