Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is appending to a list bad?

I've recently started learning scala, and I've come across the :: (cons) function, which prepends to a list.
In the book "Programming in Scala" it states that there is no append function because appending to a list has performance o(n) whereas prepending has a performance of o(1)

Something just strikes me as wrong about that statement.

Isn't performance dependent on implementation? Isn't it possible to simply implement the list with both forward and backward links and store the first and last element in the container?

The second question I suppose is what I'm supposed to do when I have a list, say 1,2,3 and I want to add 4 to the end of it?

like image 288
Travis Dixon Avatar asked Aug 24 '09 01:08

Travis Dixon


People also ask

Is appending to a list Slow?

Solution: If you append to the list using a sub routine the process slows and slows as the list grows. This does not happen if you do it inline. Even calling garbage collection makes no difference.

Is set add faster than list append?

The set is far faster, in general. Testing for membership in a list is O(n), linear in the size of the list. Adding to a set is O(1), independent of the number of the items in the list.


2 Answers

The key is that x :: somelist does not mutate somelist, but instead creates a new list, which contains x followed by all elements of somelist. This can be done in O(1) time because you only need to set somelist as the successor of x in the newly created, singly linked list.

If doubly linked lists were used instead, x would also have to be set as the predecessor of somelist's head, which would modify somelist. So if we want to be able to do :: in O(1) without modifying the original list, we can only use singly linked lists.

Regarding the second question: You can use ::: to concatenate a single-element list to the end of your list. This is an O(n) operation.

List(1,2,3) ::: List(4) 
like image 189
sepp2k Avatar answered Oct 01 '22 11:10

sepp2k


Other answers have given good explanations for this phenomenon. If you are appending many items to a list in a subroutine, or if you are creating a list by appending elements, a functional idiom is to build up the list in reverse order, cons'ing the items on the front of the list, then reverse it at the end. This gives you O(n) performance instead of O(n²).

like image 41
Chris Conway Avatar answered Oct 01 '22 12:10

Chris Conway