[erlang-questions] Indexed element access: array vs. erlang:element

Hynek Vychodil <>
Mon Aug 25 18:59:40 CEST 2008


You have typo in your code. Set on tuple can't be as fast as your measure :)
You do get on Extensible array and tuple instead of set and you call this
inside set cycle which remove data structure away.

It should be:

test(N) ->
    %% fixed-size array
    {G1, _} = timer:tc(arr, get, [{arr, array_get}, data1(N), N]),
    {S1, _} = timer:tc(arr, set, [{arr, array_set}, data1(N), N]),
    %% extensible array
    {G2, _} = timer:tc(arr, get, [{arr, array_get}, data2(N), N]),
    {S2, _} = timer:tc(arr, set, [{arr, array_set}, data2(N), N]), % <--
here
    %% tuple
    {G3, _} = timer:tc(arr, get, [{arr, tuple_get}, data3(N), N]),
    {S3, _} = timer:tc(arr, set, [{arr, tuple_set}, data3(N), N]), % <--
here
    %% results
    io:format("Fixed-size array: get: ~8wns, set: ~8wns~n", [G1 , S1]),
    io:format("Extensible array: get: ~8wns, set: ~8wns~n", [G2 , S2]),
    io:format("Tuple:            get: ~8wns, set: ~8wns~n", [G3 , S3]),
    ok.

And you should gain very different result looks like (Debian Linux 2.2GHz
Intel C2Duo Erlang/OTP R12B-3):

6> arr:test().
Fixed-size array: get:     8912ns, set:    29114ns
Extensible array: get:     8639ns, set:    15065ns
Tuple:            get:     1244ns, set:   233815ns
ok
7> arr:test(100000).
Fixed-size array: get:    78370ns, set:   110003ns
Extensible array: get:    29618ns, set:   110906ns
Tuple:            get:    12458ns, set: 27852761ns
ok

Tuple set is far slower and get is far faster than on array operation as
expected.
There is possible GC issue why Extensible array is slower than fixed. Try
run it in opposite order and you will see.

11> arr:test(100000).
Fixed-size array: get:    29036ns, set:   103593ns
Extensible array: get:    89132ns, set:   114022ns
Tuple:            get:    12471ns, set: 28103959ns
ok

Writing worth benchmark is not as simple as it looks ;-)

On Mon, Aug 25, 2008 at 5:47 PM, Joel Reymont <> wrote:

>
> On Aug 25, 2008, at 3:56 PM, Dimitry Golubovsky wrote:
>
> > Joel,
> >
> > If nobody did it before, then I'll do (not earlier than tonight
> > anyway ;)
>
>
> Here, check out the performance of fixed-size vs extensible array set
> op.
>
> Astounding!
>
> ---
>
> Mac OSX Leopard 10.5.4
>
> Mac Pro 2x2.8Ghz Quad-Core Intel Xeon, 14Gb 800Mhz DDR2 FB-DIMM
>
> Erlang (BEAM) emulator version 5.6.3 [source] [64-bit] [smp:8] [async-
> threads:0] [kernel-poll:false]
>
> %% 10K elements
>
> 14> arr:test().
> Fixed-size array: get:     1256ns, set:     6667ns
> Extensible array: get:     1255ns, set:       22ns
> Tuple:            get:      659ns, set:        6ns
> ok
>
> %% 1 million
>
> 15> arr:test(1000000).
> Fixed-size array: get:   121881ns, set:   777067ns
> Extensible array: get:   120026ns, set:       35ns
> Tuple:            get:    66288ns, set:       40ns
> ok
>
> ---
>
> -module(arr).
>
> -compile([export_all]).
>
> data1(N) ->
>     %% size implies fixed-size array
>     %% but lets be explicit
>     array:new([{size, N}, {default, 0}, {fixed, true}]).
>
> data2(N) ->
>     %% extensible array
>     array:new([{size, N}, {default, 0}, {fixed, false}]).
>
> data3(N) ->
>     erlang:make_tuple(N, 0).
>
> array_set(Array, I, Value) ->
>     %% array indexing starts at 0
>     array:set(I - 1, Value, Array).
>
> tuple_set(Tuple, I, Value) ->
>     %% tuple indexing starts at 1
>     setelement(I, Tuple, Value).
>
> array_get(Array, I) ->
>     array:get(I - 1, Array).
>
> tuple_get(Tuple, I) ->
>     element(I, Tuple).
>
> get(_, _, 0) ->
>     ok;
>
> get(Fun, Data, N) ->
>     Fun(Data, N),
>     get(Fun, Data, N - 1).
>
> set(_, _, 0) ->
>     ok;
>
> set(Fun, Data, N) ->
>     Data1 = Fun(Data, N, N),
>     set(Fun, Data1, N - 1).
>
> test() ->
>     test(10000).
>
> test(N) ->
>     %% fixed-size array
>     {G1, _} = timer:tc(arr, get, [{arr, array_get}, data1(N), N]),
>     {S1, _} = timer:tc(arr, set, [{arr, array_set}, data1(N), N]),
>     %% extensible array
>     {G2, _} = timer:tc(arr, get, [{arr, array_get}, data2(N), N]),
>     {S2, _} = timer:tc(arr, set, [{arr, array_get}, data2(N), N]),
>     %% tuple
>     {G3, _} = timer:tc(arr, get, [{arr, tuple_get}, data3(N), N]),
>     {S3, _} = timer:tc(arr, set, [{arr, tuple_get}, data3(N), N]),
>     %% results
>     io:format("Fixed-size array: get: ~8wns, set: ~8wns~n", [G1 , S1]),
>     io:format("Extensible array: get: ~8wns, set: ~8wns~n", [G2 , S2]),
>     io:format("Tuple:            get: ~8wns, set: ~8wns~n", [G3 , S3]),
>     ok.
>
>
>
> --
> wagerlabs.com
>
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



-- 
--Hynek (Pichi) Vychodil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080825/d3910be6/attachment.html>


More information about the erlang-questions mailing list