<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>