Erlang--proplists Structure Analysis

Source: Internet
Author: User
Tags compact intel core i5

The Proplists module is suitable for scenarios with less data, and is often used for processing configuration files and function options. proplists The internal data structure is the Key-value key-value pair form, the first element does the key to query and delete, if a key has more than one value will use the first occurrence of the value, Others are ignored. Proplists is extremely loose on key and value, and can be any term (). You can even make the {atom,true} abbreviation Atom. It is also because of such loose data constraints that the Proplists module does not have the means to update and append data items , you need to use Lists:replace/4.key to compare the =:= exact equals, which will determine the type and value.
5> Proplists:get_value (1,[{1,a},{1.0,b},{1,c}]) .a6> proplists:append_values (1,[{1,a},{1.0,b},{1,c}]). [a,c]8>
Specification and compression mentioned in the form of atom abbreviation, Atom form becomes the compression format, {atom,true} form becomes canonical form. This is the property of two forms, which is defined as-type property ():: Atom () | Tuple (). There is a property method in the module that specializes in data normalization.
Property ({key, true})-property, Key;property, Is_atom (key)    . The form of the call:16>  Proplists:property ({a}). {a}17>  proplists:property ({a,true}). A
Compression is actually a one-to-one element within the proplists execution PROPERTY/1, namely: [Property (P) | | P <-List].
10>  Proplists:compact ([{A, true}, {B, true}, {A, 3}, {C, true}, {A, [4]}]). [ A,B,{A,3},C,{A,[4]}]
Functions that are expanded if the calculation has compression
Unfold ([P | PS]),    if Is_atom (p)     , [{p, true} | unfold (PS)];       True,     [P | unfold (Ps)]    end;unfold ([]),    [].12>  proplists:unfold ([Foo,bar,test,haha]). [ {foo,true},{bar,true},{test,true},{haha,true}]13>  Proplists:unfold ([Foo,bar,{test,false},haha]). [ {foo,true},{bar,true},{test,false},{haha,true}]14>  proplists:unfold ([foo, "Zen", Bar,{test,false},haha]). [ {foo,true}, "Zen",{bar,true},{test,false},{haha,true}]15>  proplists:unfold ([foo, "Zen", 23,{test,false}, Haha]). [{foo,true}, "Zen", 23,{test,false},{haha,true}]
Proplists related operations take a look at the general operation of Proplists, there are some ways to pay attention to the details.

append_values(Note that less spelling of a s) combines all key values with the same data item, and value is integrated in the list.
1> Proplists:append_values (A, [{A, []}, {b, 0}, {A, 3}, {C,-1}, {A, [4]}]). [1,2,3,4]2> Proplists:append_values (A, [{A, b}, {b, 0}, {A, 3}, {C,-1}, {A, [4]}]).   [b,3,4]3> Proplists:append_values (A, [{A, b}, {b, 0}, {A, 3}, {C,-1}, {A, [[4]]}]). [b,3,[4]]1> Proplists:append_values (A, [{A, [up]}, {"Zen", 0}, {A, 3}, {C,-1}, {A, [4]}]). [1,2,3,4]2> Proplists:append_values (A, [{A, [1,2]},b]). [1,2]3> Proplists:append_values (b, [{A, [1,2]},b]). [true]4>
Deletemethod deletes all data items that are equal to the key value:
Percent Delete (Key, List), list18>  Proplists:delete (A, [{A, true}, {B, true}, {A, 3}, {C, true}, {A, [4]}]). [ {B,true},{c,true}]
CompactCompress the data
10>  Proplists:compact ([{A, true}, {B, true}, {A, 3}, {C, true}, {A, [4]}]). [ A,B,{A,3},C,{A,[4]}]

get_all_values gets all data items that are equal to the key value:

8> Proplists:get_all_values (A, [{A, [up]}, {"Zen", 0}, {A, 3}, {C,-1}, {A, [4]}]). [[1,2],3,[4]]9>

Get_boolThis method is still a bit of a trap, its intention is to see the key value when the first occurrence of the value is True|false.
Get_bool (Key, [P |                      Ps]), if Is_atom (p), p =:= Key, true; Tuple_size (P) >= 1, Element (1, P) =:= Key--Case P of {_, true}-&                                Gt                            True                                _-A-percent Don ' t continue the search!       False end; True-Get_bool (Key, Ps) End;get_bool (_key, []), False.9> Proplists:get_bool (A, [{A, [up]} {"Zen", 0}, {A, 3}, {C,-1}, {A, [4]}]) .false10> Proplists:get_bool (A, [{A,]}, {"Zen", 0}, {A, 3},a, {C,-1}, {a , [4]}]) .false11> Proplists:get_bool (A, [A,{a, [up]}, {"Zen", 0}, {A, 3},a, {C,-1}, {A, [4]}]) .true12> proplists:g  Et_bool (A, [{A,true},{a, []}, {"Zen", 0}, {A, 3},a, {C,-1}, {A, [4]}]) .true13> Proplists:get_bool (A, [{a,false},{a, [Up]}, {"Zen", 0}, {A, 3},a, {c, -1},{a, [4]}]) .false14> proplists:get_bool (q, [{A,truE},{a, [up]}, {"Zen", 0}, {A, 3},a, {C,-1}, {A, [4]}]) .false15> proplists:get_bool (q, ["abc", {A,true},{a, []}, {"Z En ", 0}, {A, 3},a, {c,-1}, {A, [4]}]) .false16> Proplists:get_bool (" abc ", [" abc ", {a,true},{a, [+]}, {" Zen ", 0}, {A, 3} , A,{c,-1}, {A, [4]}]) .false17> Proplists:get_bool ("abc", [{"ABC", True},{a,true},{a, [up]}, {"Zen", 0}, {a,3},a, {C, -1}, {A, [4]}]). True

Get_keysGet all the keys that are not duplicated
18> Proplists:get_keys ([{"ABC", True},{a,true},{a, [up]}, {"Zen", 0}, {A, 3},a,{c,-1}, {A, [4]}]). ["Zen", A,c, "abc"]19> Proplists:get_keys ([{a,true},{a,true},{a, [+]}, {"Zen", 0}, {A, 3},a, {c,-1}, {A, [4]}]). ["Zen", A,c]

Get_valueBy key, the first occurrence of value is obtained
 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.3> Proplists:get_va Lue ([A, b], ["Packet", [A, b], "Login", 22,2,s,f], "none"). " None "4> proplists:get_value (" Login ", [" Packet ", [A, b]," Login ", 22,2,s,f]," none ").  None "5> proplists:get_value (login, [" Packet ", [A, b]," Login ", 22,2,s,f]," none "). "None" 1> proplists:get_value ([A, b], ["Packet", {[A,b],bingo}, "Login", 22,2,s,f], "none") .bingo2> Proplists:get _value (S, ["packet", {[A,b],bingo}, "Login", 22,2,s,f], "none"). True3> 

look_upUnlike Get_value, the return is {Key,value}
Lookup_all
8> Proplists:lookup_all (A, [{a,1},{a, b}, {b, 0}, {A, 3}, {C,-1}, {A, [[4]]}]). [{a,1},{a,b},{a,3},{a,[[4]}]
is_definedWhether a specific key value exists
6>  proplists:is_defined (S, ["packet", {S,kill},{[a,b],bingo}, "Login", 22,2,s,f]) .true7>  proplists: Is_defined (P, ["Packet", {S,kill},{[a,b],bingo}, "Login", 22,2,s,f]) .false8>

Splitgrouping data by key value
9> Proplists:split ([{C, 2}, {e, 1}, A, {C, 3, 4}, D, {B, 5}, b], [A, B, C]). {[[a],[{b,5},b],[{c,2},{c,3,4}]],[{e,1},d]}10> Proplists:split ([{C, 2}, {c,23},{a,false},{e, 1}, A, {C, 3, 4}, D, {b, 5}, b], [A, B, C]). {[[{a,false},a],[{b,5},b],[{c,2},{c,23},{c,3,4}]],[{e,1},d]}11>

A group of the following several methods we put together to see ExpandDo is to replace the key in the list with the corresponding value, note that this method expands the object is the property
substitute_aliasesReplace the corresponding key value with an alias
1> proplists:substitute_aliases ([{zen, "Ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,1},{ 23,0}]). [{"Ligaoren", true},{"Ligaoren", zen},{abc,zen},{"Ligaoren",tick},0,{zero,1},{23,0}]2>
substitute_negationsKey value substitution, value reverse
2> proplists:substitute_negations ([{zen, "Ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,1},{ 23,0}]). [{"Ligaoren", false},{"Ligaoren", true},{abc,zen},{"Ligaoren",true},0,zero,{23,0}]3> Proplists:substitute_ Negations ([{zen, "Ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,true},{23,0}]). [{"Ligaoren", false},{"Ligaoren", true},{abc,zen},{"Ligaoren",true},0,{zero,false},{23,0}]4> proplists: Substitute_negations ([{zen, "Ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,false},{23,0}]). [{"Ligaoren", false},{"Ligaoren", true},{abc,zen},{"Ligaoren", true},0,zero,{23,0}]
NormalizeIntegrated with substitute_aliases Substitute_negations expand
2> proplists:normalize ([A,b,c,d,e,f,g],[{aliases, [{b,b2},{e,email}]}]). [a,b2,c,d,email,f,g]3> proplists:normalize ([A,b,c,d,e,f,g],[{aliases, [{b,b2},{e,email}]}]).                                                                [a,b2,c,d,email,f,g]4> proplists:normalize ([A,b,c,d,e,f,g],[{aliases, [{negations, [a,f]}]}]). [a,b,c,d,e,f,g]5> proplists:normalize ([a,b,c,d,e,f,g],[{expand, [{d,do_it_by_yourself},{g,1000}]}]).                                                   [a,b,c,do_it_by_yourself,e,f,1000]

Application examples
6> test:module_info (Compile).         
Mochiweb item parsing the header cookie uses proplist in multiple places:
Parse_form_outer (EOF, _, ACC),    lists:reverse (ACC);p Arse_form_outer ({headers, H}, Filehandler, state),    {"Form-data", H1} = Proplists:get_value ("Content-disposition", H),    Name = Proplists:get_value ("name", H1),    filename = proplists:get_value ("filename", H1), case    filename        of Undefined            (next),                    Parse_form_value (Next, {Name, []}, Filehandler, state)            end;        _-            ContentType = Proplists:get_value ("Content-type", H),            Handler = Filehandler (Filename, ContentType), Fun            (Next)-                    Parse_form_file (Next, {Name, Handler}, Filehandler, state)            end    end.

One example of parsing options:

%%% 18> proplists:lookup (Loop,[{ip, "127.0.0.1"},{loop, {mochiweb_http, default_body}}]).%%%   {Loop,{mochiweb _http,default_body}}parse_options (options),    {loop, httploop} = Proplists:lookup (loop, options),    loop = Fun (S)                   ? Module:loop (S, Httploop)           end,    Options1 = [{loop, loop} | Proplists:delete (Loop, Options)],    Mochilists:set _defaults (? DEFAULTS, Options1).

Last: Estimate 90% of the cases we only use Proplists:get_value:)

2012-8-22 Update

Proplists:get_value performance is much worse than Lists:keyfind,

Lists the following methods are BIF implementation: Percent BIFS:KEYMEMBER/3, KEYSEARCH/3, KEYFIND/3

And Proplists:get_value is Erlang implementation, I think this is the root cause of performance differences;

Here is a discussion that is basically the same judgment: http://www.ostinelli.net/erlang-listskeyfind-or-proplistsget_value/

-module (PVSL).-define (list_sizes, [10000, 100000, 1000000]).-define (retries).-compile (Export_all). Start ()- >% test for different list sizes Lists:foreach (fun (n), Test_list (n) end,? list_sizes). Test_list (listsize),% generate a list of size listsize of {Key, Val} entries keylist = [{K , K} | | K <-lists:seq (1, listsize)],% test this list against both functions Lists:foreach (Fun (Type), get_v Al (Type, Now (), Keylist, Listsize,? Retries) end, [proplists, lists]).% test getting values, compute necessary time and output print Resultsget _val (Type, start, _keylist, Listsize, 0), T = Timer:now_diff (now (), start), Io:format ("Computed ~p Rand Om key searches on a ~p-sized list in ~p ms using ~p~n ", [? Retries, Listsize, t/1000, Type]), Get_val (Proplists, Start, Keylist, Listsize, Tries), Proplists:get_value (ran Dom:uniform (listsize), keylist), Get_val (Proplists, StaRT, Keylist, Listsize, Tries-1), Get_val (lists, Start, Keylist, Listsize, Tries), Lists:keyfind (random:unifor M (listsize), 1, keylist), Get_val (lists, Start, Keylist, Listsize, Tries-1). I ran this test on my MacBook Pro, the Intel Core i5 2.4GHz with 4GB Memory, and the Erlang r13b04, with Kernel Polling enabled. These is the results.roberto$ Erl +k true +p 1000000Erlang r13b04 (erts-5.7.5) [source] [Smp:4:4] [rq:4] [async-threads:0 ] [HiPe] [Kernel-poll:true]eshell V5.7.5 (abort with ^g) 1> C (PVSL). {ok,pvsl}2> Pvsl:start (). computed-random key searches on a 10000-sized list in 323.373 ms using proplistscomputed  $ random key searches on a 10000-sized list in 12.897 ms using listscomputed-random key searches on a 100000-sized List in 3273.973 ms using proplistscomputed-random key searches on a 100000-sized list in 130.592 ms using Listscomp uted random key searches on a 1000000-sized list in 34131.905 ms using proplistscomputed-random key SeaRches on a 1000000-sized list in 2050.627 ms using listsok3> 

Erlang--proplists Structure Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.