# [erlang-questions] Performance of maps:get()

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Wed May 18 15:52:41 CEST 2016

```Rewriting into a module and passing through eministat:

-module(maps_get).

-export([datasets/0, t/0]).

without(Map) ->
K1 = {a, 1},
K2 = {a, 2},
K3 = {a, 3},
#{K1 := V1, K2 := V2, K3 := V3} = Map,
{V1, V2, V3}.

with(Map) ->
{maps:get({a,1}, Map),
maps:get({a,2}, Map),
maps:get({a,3}, Map)}.

datasets() ->
Map = #{{a, 1} => 100, {a, 2} => 200, {a, 3} => 300},
[eministat:s("without", fun() -> without(Map) end, 100, us),
eministat:s("with", fun() -> with(Map) end, 100, us)].

t() ->
[Without | With] = datasets(),
eministat:x(95.0, Without, With).

yields the following result:

9> maps_get:t().
x without
+ with
+--------------------------------------------------------------------------+
|    *      *     +                                                x      x|
|    *      *                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    *      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +      x                                                              |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
|    +                                                                     |
||________A_M_______|                                                      |
|  |_A_|                                                                   |
+--------------------------------------------------------------------------+
Dataset: x N=100 CI=95.0000
Statistic     Value     [         Bias] (Bootstrapped LB‥UB)
Min:         0.00000e+0
1st Qu.      0.00000e+0
Median:         1.00000
3rd Qu.         1.00000
Max:            10.0000
Average:       0.820000 [  -8.45000e-4] (     0.630000 ‥       1.23000)
Std. Dev:       1.33621 [  -7.87598e-2] (     0.482418 ‥       2.33919)

Outliers: 0/2 = 2 (μ=0.819155, σ=1.25745)
Outlier variance:      0.989942 (severe, the data set is probably
unusable)

------

Dataset: + N=100 CI=95.0000
Statistic     Value     [         Bias] (Bootstrapped LB‥UB)
Min:         0.00000e+0
1st Qu.      0.00000e+0
Median:      0.00000e+0
3rd Qu.      0.00000e+0
Max:            2.00000
Average:     4.00000e-2 [  -4.33000e-4] (   0.00000e+0 ‥      0.110000)
Std. Dev:      0.242878 [  -2.09268e-2] (     0.100000 ‥      0.455716)

Outliers: 0/3 = 3 (μ=3.95670e-2, σ=0.221952)
Outlier variance:      0.989996 (severe, the data set is probably
unusable)

Difference at 95.0% confidence
-0.780000 ± 0.266188
-95.1220% ± 32.4620%
(Student's t, pooled s = 0.960324)
------

The result is largely unusable. We can't measure at the microsecond level
precisely enough to conclude anything. You will probably have to run
several rounds of the selection in order to get a useful value which isn't
severely pertubed by e.g. garbage collection or taking an interrupt on the
OSX machine I ran this on. You will have to do something about the outlier
variance.

Also note that the confidence intervals overlaps a lot. Even though we have
significant difference at 95.0% confidence, the difference is probably
affected too much by measurement errors to be conclusive. A test could
easily run 1000 rounds of the operation:

Altering the code to 10000 rounds and 25 trials yields the following code:

-module(maps_get).

-export([datasets/0, t/0]).

without(0, _) -> ok;
without(K, Map) ->
K1 = {a, 1},
K2 = {a, 2},
K3 = {a, 3},
#{K1 := V1, K2 := V2, K3 := V3} = Map,
{V1, V2, V3},
without(K-1, Map).

with(0, _) -> ok;
with(K, Map) ->
{maps:get({a,1}, Map),
maps:get({a,2}, Map),
maps:get({a,3}, Map)},
with(K-1, Map).

datasets() ->
Map = #{{a, 1} => 100, {a, 2} => 200, {a, 3} => 300},
[eministat:s("without", fun() -> without(10000, Map) end, 25, us),
eministat:s("with", fun() -> with(10000, Map) end, 25, us)].

t() ->
[Without | With] = datasets(),
eministat:x(95.0, Without, With).

And the following output from eministat:

11> maps_get:t().
x without
+ with
+--------------------------------------------------------------------------+
| x xx x x                                                          +     +|
| x      x                                                          +      |
| x      x                                                          +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
| x                                                                 +      |
|                                                                   +      |
|                                                                   +      |
|                                                                   +      |
|                                                                   +      |
|                                                                   +      |
||MA__|                                                                    |
|                                                                  |A|     |
+--------------------------------------------------------------------------+
Dataset: x N=25 CI=95.0000
Statistic     Value     [         Bias] (Bootstrapped LB‥UB)
Min:            408.000
1st Qu.         410.000
Median:         411.000
3rd Qu.         412.000
Max:            460.000
Average:        418.880 [  -2.47040e-2] (      413.760 ‥       426.680)
Std. Dev:       16.3078 [    -0.661582] (      10.6226 ‥       21.5513)

Outliers: 0/6 = 6 (μ=418.855, σ=15.6462)
Outlier variance:      0.149444 (moderate)

------

Dataset: + N=25 CI=95.0000
Statistic     Value     [         Bias] (Bootstrapped LB‥UB)
Min:            860.000
1st Qu.         860.000
Median:         861.000
3rd Qu.         861.000
Max:            902.000
Average:        862.440 [  -9.31200e-3] (      860.680 ‥       869.040)
Std. Dev:       8.26680 [     -1.72872] (     0.583095 ‥       16.8891)

Outliers: 0/1 = 1 (μ=862.431, σ=6.53808)
Outlier variance:    3.84000e-2 (slight)

Difference at 95.0% confidence
443.560 ± 7.35359
105.892% ± 1.75554%
(Student's t, pooled s = 12.9283)
------

ok
12>

Conclusion: maps:get/2 is likely around 443us (+/- 7.4us) slower in this
test than ignoring it. But also note that in both cases the compiler is
warning us about term construction which is unused. So the compiler might
optimize stuff away. Though running a loop with no effect as a control
ticks out at 170us, so it is unlikely.

On Wed, May 18, 2016 at 1:55 PM, Dmitry Belyaev <be.dmitry@REDACTED> wrote:

> As a first step try a compiled version, not a test in a shell.
>
> On 18 May 2016 1:35:49 PM AEST, Avinash Dhumane <nistrigunya@REDACTED>
> wrote:
>>
>> For my algorithm trading application, gains even in 5 to 10 microseconds
>> matter.
>>
>> I used maps extensively to improve expressiveness of the design.
>>
>> But, here is a small observation about maps. I am not sure if the
>> performance variation seen is indeed true, or if my test case is wrong. In
>> either case, please point me to the right way of efficiently using of maps.
>>
>> avinash@REDACTED:~/tws\$ erl
>> Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:2:2] [async-threads:10]
>> [hipe] [kernel-poll:false]
>>
>> Eshell V7.3  (abort with ^G)
>>
>> %%% compute average of timer:tc() return values (timings)
>>
>> 1> Avg = fun(PerfList) -> Sum = lists:sum(lists:map(fun({Time, _}) ->
>> Time end, PerfList)), Len = erlang:length(PerfList), Sum div Len  end.
>> #Fun<erl_eval.6.50752066>
>>
>> %%% a test map of size 3
>>
>> 2> Map = #{{a, 1} => 100, {a, 2} =&gt ; 200, {a, 3} => 300}.
>>
>> #{{a,1} => 100,{a,2} => 200,{a,3} => 300}
>>
>> %%% performance: without maps:get()
>>
>> 3> PerfList1 = lists:map(fun(_) -> timer:tc(fun() -> K1 = {a, 1}, K2 =
>> {a, 2}, K3 = {a, 3}, #{K1 := V1, K2 := V2, K3 := V3} = Map, {V1, V2, V3}
>> end) end, lists:seq(1,100)).
>> [{111,{100,200,300}},
>>  {81,{100,200,300}},
>>  {88,{100,200,300}},
>> .....details deleted.....
>>  {91,{100,200,...}},
>>  {83,{100,...}},
>>  {85,{...}},
>>  {107,...},
>>  {...}|...]
>>
>> %%% performance: with maps:get()
>>
>> 4> PerfList2 = lists:map(fun(_) -> timer:tc(fun() -> {maps:get({a,1},
>> Map), maps:get({a,2}, Map), maps:get({a,3}, Map)} end) end, lists:seq(1,
>> 100)).
>> [{13,{100,200,300}},
>>  {12,{100,200,300}},
>>  {33,{100,200,300}},
>> .....details deleted.....
>>  {13,{100,200,...}},
>>  {12,{100,...}},
>>  {12,{...}},
>>  {12,...},
>>  {...}|...]
>>
>> %%% compare performance: maps:get() is 7-times faster
>>
>> 5> {Avg(PerfList1), Avg(PerfList2)}.
>> {89,13}
>> 6>
>>
>> ------------------------------
>>
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
> --
> Best wishes,
> Dmitry Belyaev
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>

--
J.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160518/d75cb7fb/attachment.htm>
```