Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a module that implements an efficient array type in Erlang?

I have been looking for an array type with the following characteristics in Erlang.

append(vector(), term())        O(1) 
nth(Idx, vector())              O(1)
set(Idx, vector(), term())      O(1)
insert(Idx, vector(), term())   O(N)
remove(Idx, vector())           O(N)

I normally use a tuple for this purpose, but the performance characteristics are not what I would want for large N. My testing shows the following performance characteristics...

erlang:append_element/2          O(N).
erlang:setelement/3              O(N).

I have started on a module based on the clojure.lang.PersistentVector implementation, but if it's already been done I won't reinvent the wheel.

Edit:

For those interested, I've finished implementing vector.erl ... using the same algorithm as clojure.lang.PersistentVector. It has similar performance characteristics as the array module, but has slightly better constant factors on append.

The the following test appends 10000 items per interval and then does 10000 lookups and 10000 updates at random index. All operations are near O(1). The timings in the inner tuple are in microseconds.

3> seq_perf:test(vector, 100000, 10).
{2685854,
 {ok,[{100000,{66966,88437,124376}},
      {200000,{66928,76882,125677}},
      {300000,{68030,76506,116753}},
      {400000,{72429,76852,118263}},
      {500000,{66296,84967,119828}},
      {600000,{66953,78155,116984}},
      {700000,{65996,77815,138046}},
      {800000,{67801,78455,118191}},
      {900000,{69489,77882,114886}},
      {1000000,{67444,80079,118428}}]}}
4> seq_perf:test(array, 100000, 10). 
{2948361,
 {ok,[{100000,{105482,72841,108828}},
      {200000,{123655,78898,124092}},
      {300000,{110023,76130,106806}},
      {400000,{104126,73830,119640}},
      {500000,{104771,72593,110157}},
      {600000,{107306,72543,109713}},
      {700000,{122066,73340,110662}},
      {800000,{105853,72841,110618}},
      {900000,{105267,73090,106529}},
      {1000000,{103445,73206,109939}}]}}
like image 282
dsmith Avatar asked Sep 12 '12 19:09

dsmith


1 Answers

Those properties are not possible in a purely functional implementation. The array module (http://www.erlang.org/doc/man/array.html) is a quite good compromise, but if you require O(1) lookup and update, you'll have to use an ETS table instead.

like image 96
RichardC Avatar answered Sep 28 '22 03:09

RichardC