关于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接口实现的。

原文地址:https://www.cnblogs.com/unqiang/p/4538969.html