<div dir="ltr">I observed a strange performance degradation in dict.  Let me share the code I used in the test first.<div><br></div><div><br></div><div>    -module(data).</div><div>    -export([start_link/1, get/1, get_concurrent/1]).</div><div>    -export([init/0]).</div><div><br></div><div>    start_link() -></div><div>      proc_lib:start_link(?MODULE, init, []).</div><div><br></div><div>    init() -><br></div><div>      register(?MODULE, self()),</div><div>      % Initialize data:</div><div>      % 0 => [],</div><div>      % 1 => [1],</div><div>      % 2 => [1,2]</div><div>      % ...</div><div>      Dict = lists:foldl(</div><div>        fun (Key, Dict0) -> dict:store(Key, value(Key), Dict0) end,</div><div>        dict:new(), lists:seq(0, 255)</div><div>      ),</div><div>      proc_lib:init_ack({ok, self()}),</div><div>      loop(Dict).</div><div><br></div><div>    value(Key) -></div><div>        lists:seq(1, Key).</div><div><br></div><div>    loop(Dict) -><br></div><div>      receive</div><div>        {get, Key, From} -></div><div>          case dict:find(Key, Dict) of</div><div>            {ok, Value} -> From ! Value;</div><div>            error -> From ! undefined</div><div>          end;</div><div>        _ -></div><div>          ok</div><div>      end,</div><div>      loop(Dict).</div><div><br></div><div>    get(Key) -><br></div><div>      ?MODULE ! {get, Key, self()},</div><div>      receive</div><div>        Value -> Value</div><div>      end.</div><div><br></div><div>    %% Run get N times and return average execution time.</div><div>    -spec get_concurrent(integer()) -> number().</div><div>    get_concurrent(N) -></div><div>      Profiler = self(),</div><div>      Workers = [</div><div>         prof_lib:spawn_link(</div><div>           fun () -></div><div>             Key = erlang:system_time() rem 255,</div><div>             Result = timer:tc(?MODULE, get, [Key]),</div><div>             Profiler ! {self(), Result}</div><div>           end</div><div>         ) || _ <- lists:seq(1, N)</div><div>       ],</div><div>       Ts = receive_all(Workers, []),</div><div>       lists:sum(Ts) / length(Ts).</div><div><br></div><div>    receive_all([], Ts) -></div><div>      Ts;</div><div>    receive_all(Workers, Ts) -></div><div>      receive</div><div>        {Worker, {T, _}} -> receive_all(lists:delete(Worker, Workers), [T | Ts])</div><div>      end.</div><div><br></div><div><br></div><div>When I ran the test in the shell, I got.</div><div><br></div><div>    1> data:start_link().<br></div><div>    {ok, <0.6497.46>}</div><div>    2> timer:tc(data, get, [5]).</div><div>    {23,[1,2,3,4,5]}</div><div><br></div><div><br></div><div>I could get a value in 23 microseconds and expected something not too slower results for concurrent get but,</div><div><br></div><div>    3> data:get_concurrent(100000).</div><div>    19442.828</div><div><br></div><div><br></div><div>The value 19442.828 microseconds seemed to be too big a value so I tested with different values such as large binaries and tuples.  And this time the same get_concurrent(100000) gave me 200 something microseconds.</div><div><br></div><div>I also tried the same with an ets instead of a dict, but there was no such performance degradation by the value type.</div><div><br></div><div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Park, Sungjin<div>-------------------------------------------------------------------------------------------------------------------</div><div>Peculiar travel suggestions are dancing lessons from god.</div><div>  -- The Books of Bokonon</div><div>-------------------------------------------------------------------------------------------------------------------</div></div>
</div></div>