Erlang 对dict、maps、array的部分性能测试

发布时间 2023-05-29 17:56:11作者: J6`

竖轴:时间(微秒)横轴(数据量)
备注(maps与dict的key是{name,整数}与整数在速度上差别不大,array的key是正整数)

结论

数据量在32-10000用maps的各种操作速度更快(但内存稍多,引用官方描述,此处没测)
数据量1万以上,如果键是正整数,array与maps性能相当(官方推荐用array)
数据量接近32个的时候是maps速度最差的时候

数据

数据规模 dict_from_list map_from_list array_from_list dict_store map_store array_store dict_get map_get array_get
500000 10297100 125000 15000 21124886 1061986 1079010 828007 218000 359999
100000 546995 30999 16000 6890939 1030991 1078009 327997 217998 359003
50000 188000 15000 0 4016023 875004 1063006 359001 125000 375001
10000 16000 0 0 1140008 516004 1000007 312002 94000 360002
1000 0 0 0 687009 250003 985013 250003 94001 359004
100 0 0 0 641001 187000 969001 234000 63000 359000
32 0 0 0 515000 422000 953001 172000 312000 360000
10 0 0 0 467994 171998 1014988 156998 139998 359996

环境

设备名称 DESKTOP-KM7LG14
处理器 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz 3.19 GHz
机带 RAM 16.0 GB
设备 ID 4EABE4D6-DF57-4C5E-8606-7160E603E929
产品 ID 00330-50000-00000-AAOEM
系统类型 64 位操作系统, 基于 x64 的处理器
笔和触控 没有可用于此显示器的笔或触控输入
版本 Windows 10 专业版
版本号 21H1
安装日期 ‎2020/‎11/‎23
操作系统内部版本 19043.1348
体验 Windows Feature Experience Pack 120.2212.3920.0

代码


dmt(Size, N) ->
    {TD, D} = timer:tc(dict, from_list, [[{{dict, I}, I} || I <- lists:seq(1, Size)]]),
    {TM, M} = timer:tc(maps, from_list, [[{{maps, I}, I} || I <- lists:seq(1, Size)]]),
    {TA, _A} = timer:tc(array, from_list, [lists:seq(1, Size)]),
    {TA2, A2} = timer:tc(?MODULE, array_store, [N, Size, array:new()]),
    {TD1, _} = timer:tc(?MODULE, dict_get, [N, Size, D]),
    {TM1, _} = timer:tc(?MODULE, maps_get, [N, Size, M]),
    {TA1, _} = timer:tc(?MODULE, array_get, [N, Size, A2]),
    {TD2, _} = timer:tc(?MODULE, dict_store, [N, Size, dict:new()]),
    {TM2, _} = timer:tc(?MODULE, maps_store, [N, Size, maps:new()]),
    io:format("Size-~p N-~p:init[~p:~p:~p] store[~p:~p:~p] get[~p:~p:~p]", [Size, N, TD, TM, TA, TD2, TM2, TA2, TD1, TM1, TA1]).

dict_get(N, Size, Dict) ->
    dict:find({dict, (N rem Size) bor (2001 bsl 23)}, Dict),
    if  
        N > 0 ->
            dict_get(N - 1, Size, Dict);
        true ->
            ok
    end.


maps_get(N, Size, Map) ->
    maps:find({maps, (N rem Size) bor (2001 bsl 23)}, Map),
    if  
        N > 0 ->
            maps_get(N - 1, Size, Map);
        true ->
            ok
    end.

dict_store(N, Size, Dict) ->
    K = (N rem Size) bor (2001 bsl 23),
    Dict1 = dict:store({dict, K}, K, Dict),
    if  
        N > 0 ->
            dict_store(N - 1, Size, Dict1);
        true ->
            Dict1
    end.


maps_store(N, Size, Map) ->
    K = (N rem Size) bor (2001 bsl 23),
    Map1 = maps:put({maps, K}, K, Map),
    if  
        N > 0 ->
            maps_store(N - 1, Size, Map1);
        true ->
            Map1
    end.

array_get(N, Size, Array) ->
    catch array:get((N rem Size) bor (2001 bsl 23), Array),
    if 
        N > 0 ->
            array_get(N - 1, Size, Array);
        true ->
            ok
    end.

array_store(N, Size, Array) ->
    K = (N rem Size) bor (2001 bsl 23),
    Array1 = array:set(K, N, Array),
    if 
        N > 0 ->
            array_store(N - 1, Size, Array1);
        true ->
            Array1
    end.