我发现"函数ets:select/2和mnesia:select/3应该优先于ets:match/2、ets:matche_object/2和mnasia:match_object/3"表单ref链接:http://www.erlang.org/doc/efficiency_guide/tablesDatabases.html
我读过一些关于选择和匹配之间比较的文章,我认为有一些因素会影响结果,如表中记录的数量、是否选择/匹配主键、表类型(包、套…)等。
在我的测试中,我对所有类型的10W记录和1W记录的表都这样做,并且只选择/匹配非主键。
代码如下:
select_ets_test(Times) ->
MS = ets:fun2ms(fun(T) when T#ets_haoxian_template.count == 15 -> T end),
T1 = timer:tc(?MODULE, todo, [fun() -> ets:select(haoxian_test_bag, MS) end, Times]),
T2 = timer:tc(?MODULE, todo, [fun() -> ets:select(haoxian_test_set, MS) end, Times]),
T3 = timer:tc(?MODULE, todo, [fun() -> ets:select(haoxian_test_ordered_set, MS) end, Times]),
T4 = timer:tc(?MODULE, todo, [fun() -> ets:select(haoxian_test_duplicate_bag, MS) end, Times]),
io:format("select bag : ~p~n", [T1]),
io:format("select set : ~p~n", [T2]),
io:format("select ordered_set : ~p~n", [T3]),
io:format("select duplicate bag : ~p~n", [T4]).
match_ets_test(Times) ->
MS = #ets_haoxian_template{count = 15, _ = '_' },
T1 = timer:tc(?MODULE, todo, [fun() -> ets:match_object(haoxian_test_bag, MS) end, Times]),
T2 = timer:tc(?MODULE, todo, [fun() -> ets:match_object(haoxian_test_set, MS) end, Times]),
T3 = timer:tc(?MODULE, todo, [fun() -> ets:match_object(haoxian_test_ordered_set, MS) end, Times]),
T4 = timer:tc(?MODULE, todo, [fun() -> ets:match_object(haoxian_test_duplicate_bag, MS) end, Times]),
io:format("match bag : ~p~n", [T1]),
io:format("match set : ~p~n", [T2]),
io:format("match ordered_set : ~p~n", [T3]),
io:format("match duplicate bag : ~p~n", [T4]).
todo(_Fun, 0) ->
ok;
todo(Fun, Times) ->
Fun(),
todo(Fun, Times - 1).
记录想要:#ets_haoxy_template{type=X,count=Y,…},keypose是类型。
结果如下:1W测试:
insert bag : {324000,true}
insert set : {221000,true}
insert ordered_set : {108000,true}
insert duplicate bag : {173000,true}
select bag : {284000,ok}
select set : {255000,ok}
select ordered_set : {221000,ok}
select duplicate bag : {252000,ok}
match bag : {238000,ok}
match set : {192000,ok}
match ordered_set : {136000,ok}
match duplicate bag : {191000,ok}
10W测试:
insert bag : {1654000,true}
insert set : {1684000,true}
insert ordered_set : {981000,true}
insert duplicate bag : {1769000,true}
select bag : {3404000,ok}
select set : {3433000,ok}
select ordered_set : {2501000,ok}
select duplicate bag : {3678000,ok}
match bag : {2749000,ok}
match set : {2927000,ok}
match ordered_set : {1748000,ok}
match duplicate bag : {2923000,ok}
看起来匹配比选择好?或者我的测试出了问题???
match
函数使用特殊的元组语法(match_pattern
)来决定返回什么。
select
函数采用了一种特殊的元组语法(match_spec
),它是match_pattern
的超集,能够指定保护并从结果集中提取元素(而不仅仅是返回匹配的键)。
我的理解是:
select
将match_spec
编译成一个匿名函数,加快了它的运行速度- 为该功能提供保护的能力比仅使用
match_pattern
更快地消除误报(因为它们将首先运行) - 从结果集中提取元素的能力可以节省您以后必须做的工作,而不是迭代返回的键来提取数据
在琐碎的非特定用例中,select
只是围绕match
做的大量工作。在非琐碎的更常见的用例中,select
会更快地为您提供真正想要的东西。