关于proplists:get_value/2 与lists:keyfind/3 的效率比较
关于proplists:get_value/2 与lists:keyfind/2 的效率 早有比较,已出结论,lists:keyfind/2 的效率要好很多,好些人都是直接用或者做过它们之间的比较测试,测试下就一目了然了,直接上代码:
1 -module(a). 2 3 -compile(export_all). 4 5 test() -> 6 Y = "a", 7 List = [{X,Y} || X<- lists:seq(1,10)], 8 {Timer1,_} = timer:tc(lists,map,[fun(X) -> proplists:get_value(X,List)end, lists:seq(1,100000)]), 9 io:format("proplists.......~p~n",[Timer1]), 10 {Timer2,_} = timer:tc(lists,map,[fun(X) -> lists:keyfind(1,X,List)end, lists:seq(1,100000)]), 11 io:format("lists.......~p~n",[Timer2]), 12 ok.
结果很清楚,分别执行10万次,time分别为60000和10000微秒,而且调用次数越多,差异越明显。很明显lists:keyfind/2 的效率要好很多。
附个老外较早之前测试的链接:http://www.ostinelli.net/erlang-listskeyfind-or-proplistsget_value
比较下这两个的具体实现:
看下源码:
-spec get_value(Key, List, Default) -> term() when Key :: term(), List :: [term()], Default :: term(). get_value(Key, [P | Ps], Default) -> if is_atom(P), P =:= Key -> true; tuple_size(P) >= 1, element(1, P) =:= Key -> case P of {_, Value} -> Value; _ -> %% Don</code>t continue the search! Default end; true -> get_value(Key, Ps, Default) end; get_value(_Key, [], Default) -> Default.
%% Shadowed by erl_bif_types: lists:keyfind/3 -spec keyfind(Key, N, TupleList) -> Tuple | false when Key :: term(), N :: pos_integer(), TupleList :: [Tuple], Tuple :: tuple(). keyfind(_, _, _) -> erlang:nif_error(undef).
很明显:可以看到,proplists:get_value/2 是遍历递归实现的,而lists:keyfind/3是调用nif接口实现的。