Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is lookup in an Array O(1)?

Tags:

arrays

big-o

ruby

I believe that in some languages other than Ruby, an Array lookup is O(1) because you know where the data starts, and you multiply the index by the size of the data the array is holding, and then access that memory location.

However, in Ruby, an Array can have objects from different classes, so how does it manage to do a lookup of O(1) complexity?

like image 274
blackghost Avatar asked Aug 28 '14 05:08

blackghost


People also ask

Why is accessing an array O 1?

This is done in O(1) because it is pretty simple (constant number of math calculations) where the element is located given the index, the beginning of the array and the size of each element.

Why is the complexity of fetching from an array be O 1?

Because the index n of an array points to the n+1th element in the array (using zero-based indexing).

Is array lookup O 1?

An array is a linear data structure. In an array, the operation to fetch a value takes constant time i.e., O(1). Let us see why is it so.

How does array lookup work?

The array form of LOOKUP looks in the first row or column of an array for the specified value and returns a value from the same position in the last row or column of the array. Use this form of LOOKUP when the values that you want to match are in the first row or column of the array.


2 Answers

What @Neil Slater said, with a little more detail…

There are basically two plausible approaches to storing an array of heterogeneous objects of differing sizes:

  1. Store the objects as a singly- or doubly-linked list, with the storage space for each individual object preceded by pointer(s) to the preceding and/or following objects. This structure has the advantage of making it very easy to insert new objects at arbitrary points without shifting around the rest of the array, but the huge downside is that looking up an object by its position is generally O(N), since you have to start from one end of the list and jump through it node-by-node until you arrive at the n-th one.

  2. Store a table or array of constant-sized pointers to the individual objects. Since this lookup table contains constant-sized items in a contiguous ordered layout, looking up the addresses of individual objects O(1); the table is just a C-style array, in which lookup only takes 1-to-a-few machine instructions, even on RISC CPU architectures.

(The allocation strategies for storing the individual objects are also interesting and complex, but not immediately relevant to your question.)

Dynamic languages like Perl/Python/Ruby pretty much all opt for #2 for their general-purpose list/array types. In other words, they make lookup more efficient than inserting objects at random locations in the list, which is the better choice for many applications.

I'm not familiar with the implementation details for Ruby, but they are likely quite similar to those of Python's list type, whose performance and design is explained in wonderful detail at effbot.org.

like image 200
Dan Lenski Avatar answered Nov 03 '22 05:11

Dan Lenski


Its implementation probably contains an array of memory addresses, pointing to the actual objects. Therefore it can still lookup without looping through the array.

like image 36
lulalala Avatar answered Nov 03 '22 06:11

lulalala