Use and optimization suggestions of erlang list, erlanglist

Source: Internet
Author: User

Use and optimization suggestions of erlang list, erlanglist

Erlang has two composite structures: tuple and list. The difference between the two is that the number of child elements of tuple is fixed and cannot be changed after declaration. The list is variable, you can use [H | T] to retrieve or insert new elements. In the previous article, I talked about tuple-related content. In this article, I will talk about erlang list, mainly about some basic operations and commonly used list functions, and some optimization points.

Basic list operations

1> A = [1, 2, 3, "abc"].[1,2,3,"abc"]2> length(A).43> is_list(A).true4> list_to_binary(A).<<1,2,3,97,98,99>>5> list_to_bitstring(A).<<1,2,3,97,98,99>>6> [A1|A2] = A.[1,2,3,"abc"]7> A1.18> A2.[2,3,"abc"]9> hd(A).110> tl(A).[2,3,"abc"]11> B = [0|A].[0,1,2,3,"abc"]


List Function DescriptionCommon lists Functions

This section describes some commonly used lists functions. For more information, see the erlang lists document.

Lists: foreach (Fun, List)-> OK

1> lists:foreach(fun(X) -> io:format("~p~n", [X]) end, [1,2,3]).123ok

In this example, we traverse the list [1, 2, 3] and give the retrieved element to X until the traversal ends, and finally return OK.


Lists: foldl (Fun, Acc0, List)-> Acc1

2> lists:foldl(fun(X, Sum) -> X + Sum end, 0, [1,2,3,4,5]).15

In this example, 0 specifies the initial value of Sum. By traversing the list [1, 2, 3, 4, 5], the retrieved element is given to X, and then the X + Sum is calculated, the result is passed to Sum in the next traversal until the result of X + Sum is returned.

The following is the implementation of lists: foldl/3, which is actually a tail recursion function.

Foldl (F, Accu, [Hd | Tail])->
Foldl (F, F (Hd, Accu), Tail );
Foldl (F, Accu, []) when is_function (F, 2)->

Accu.


Lists: reverse (List1)-> List2

3> lists:reverse([1,2,3,4,5]).[5,4,3,2,1]

List inversion (this is a bif function with high efficiency)


Lists: flatten (DeepList)-> List

4> lists:flatten([1,[2,3],[4,[5]],6]).[1,2,3,4,5,6]

The lists is flattened and the list with a deep structure is converted into a simple list. This function has performance overhead, which is described later in this article.


Lists: member (Elem, List)-> boolean ()

5> lists:member(3,[1,2,3]).true

Check whether the element is in the list (this is a bif function, which is more efficient)


Lists: sort (List1)-> List2

6> lists:sort([2,3,1]).[1,2,3]

Sort the lists elements from small to large. to customize the sorting rules, you can use lists: sort/2.


Lists: sort (Fun, List1)-> List2

7> lists:sort(fun(A,B)-> A>=B end,[2,3,1]).[3,2,1]


Lists function for processing TupleList

TupleList is a list of tuple elements. erlang provides some interfaces to process such data.

Lists: keymember (Key, N, TupleList)-> boolean ()

8> lists:keymember(b,1,[{a,1,1},{b,1,1},{c,1,1}]).true
Check whether the list contains a tuple with the Key position N (this is a bif function with high efficiency)


Lists:Keyfind (Key, N, TupleList)-> Tuple | false

9> lists:keyfind(b,1,[{a,1,1},{b,1,1},{c,1,1}]).{b,1,1}
Returns the tuple with the nth position as the Key in the list. If no value is found, false is returned.

Note:

1. Find the first matched tuple and return it. If no matching tuple is found, false is returned.

2. This interface can be used instead of lists: keysearch (Key, N, TupleList)

3. This is a bif function with high efficiency.

The official documentation of lists: keysearch (Key, N, TupleList) includes the following:

This function is retained for backward compatibility. The function lists: keyfind/3 (introduced in R13A) is in most cases more convenient.

This means that lists: keysearch/3 is only used to maintain backward compatibility. It is more convenient to use lists: keyfind/3.


Lists:Keytake (Key, N, TupleList1)-> {value, Tuple, TupleList2} | false

10> lists:keytake(b,1,[{a,1,1},{b,1,1},{c,1,1}]).{value,{b,1,1},[{a,1,1},{c,1,1}]}
Returns the tuple with the nth position as the Key in the list, and returns the tuple and the remaining TupleList. If no value is found, false is returned.

Note: Find the first matched tuple and return it.


Lists:Keyreplace (Key, N, TupleList1, NewTuple)-> TupleList2

11> lists:keyreplace(b,1,[{a,1,1},{b,1,1},{c,1,1}], {b,2,2}).[{a,1,1},{b,2,2},{c,1,1}]

Replace the tuple with the nth position as the Key in the list (only Replace the first tuple found)


Lists:Keystore (Key, N, TupleList1, NewTuple)-> TupleList2

12> lists:keystore(b,1,[{a,1,1},{b,1,1},{c,1,1}],{b,2,2}).[{a,1,1},{b,2,2},{c,1,1}]
Replace the tuple with the nth position as the Key in the list and return the new TupleList. NewTuple cannot be appended to original TupleList and returned. This is different from lists: keyreplace/4.

Note: Only Replace the first tuple


Lists function comments BIF Functions

Some lists functions have been optimized to bif functions with high efficiency. There are the following:

Lists: member/2, lists: reverse/2, lists: keymember/3, lists: keysearch/3, lists: keyfind/3


Functions with poor performance

Below are some functions with poor implementation performance. It is not recommended to use a long list. It doesn't matter if a short list is used:

1) lists: foldr/3

Non-tail recursion. If the sequence is very important, you can use lists: reverse/1 after lists: foldl/3, or lists: reverse/1 after lists: foldl/3.

Lists: foldr is similar to lists: foldl. The difference is that foldr starts from the last element of the list and implements non-tail recursion. It is not recommended to use a long list.

foldr(F, Accu, [Hd|Tail]) ->    F(Hd, foldr(F, Accu, Tail));foldr(F, Accu, []) when is_function(F, 2) ->    Accu.

2) lists: append/2

Implemented as append (L1, L2)-> L1 ++ L2. among them, L1 ++ L2 traverses L1. If you must use it, place the short list to the left.

3) lists: subtract/2

Implemented as subtract (L1, L2)-> L1 -- L2. the complexity of -- is proportional to the product of its operand length. The alternative is as follows:

Set = gb_sets:from_list(L2),  [E || E <- L1, not gb_sets:is_element(E, Set)].

NOTE: If L1 contains repeated elements, the above Code is different from --, and -- will not delete all repeated elements.

13> [1,2,3,4,2] -- [2,3].[1,4,2]

4) lists: flatten/1

This is a flat list function, which has performance overhead. erlang's official documentation also describes:
Lists: flatten/1 builds an entirely new list. Therefore, it is expensive, and even more expensive than the ++ (which copies its left argument, but not its right argument ).
It copies all nested elements in DeepList to generate a new list, which is costly and is not recommended for long lists.

flatten(List) when is_list(List) ->    do_flatten(List, []).flatten(List, Tail) when is_list(List), is_list(Tail) ->    do_flatten(List, Tail).do_flatten([H|T], Tail) when is_list(H) ->    do_flatten(H, do_flatten(T, Tail));do_flatten([H|T], Tail) ->    [H|do_flatten(T, Tail)];do_flatten([], Tail) ->    Tail.

5) functions implemented by non-tail recursion in lists:

Lists: map/2, lists: flatmap/2, lists: zip/2, lists: delete/2, lists: sublist/2, lists: sublist/3, lists: takewhile/2, lists: concat/1
Lists: flatten/1, lists: keydelete/3, lists: keystore/4, lists: zf/2, lists: mapfoldl/3, lists: mapfoldr/3, lists: foldr/3


Lists functions with anonymous Functions

Lists has many functions with parameters of anonymous functions, including the following functions:

Lists: foldl/3, lists: foldr/3, lists: foreach/2, lists: sort/2, lists: usort/2, lists: merge/3, lists: umerge/3, lists: keymap/3, lists: flatmap/2

What are the problems with using anonymous functions?

Normal Functions are optimized during erlang compilation, while anonymous functions need to be dynamically generated during code execution, resulting in a certain amount of consumption. Although the process of anonymous functions has optimized the cost of local functions, address redirection cannot be avoided Based on context values. Erlang may continue to improve anonymous functions in the future.

Optimization of lists anonymous function processing:

1) Function Assignment

The first problem is not to write such code in a loop:

14> [lists:foldl(fun(X, Sum) -> X + Sum end, 0, [1,2,3,4,5]) || X <- lists:seq(1,5)].[15,15,15,15,15]
In the above Code, the anonymous function is generated every time, which can be modified as follows:

17> Fun = fun(X, Sum) -> X + Sum end.#Fun<erl_eval.12.82930912>18> [lists:foldl(Fun, 0, [1,2,3,4,5]) || X <- lists:seq(1,5)].[15,15,15,15,15]
The anonymous function Fun only needs to be generated once and put as a parameter to the lists function.

2) function localization

The so-called localization is to write the anonymous function as a local function and then pass it as a parameter to the lists function, as shown below:

test() ->    lists:foldl(fun sum/2, 0, [1,2,3,4,5]).sum(X, Sum) ->    X + Sum.
Although anonymous functions are also dynamically generated here, they are only used for address redirection. If you are interested, you can print the assembly code to see the specific situation.

List Parsing

When talking about lists, I have to talk about list resolution. I have also talked about list resolution in my previous articles. The basic form of list Parsing is as follows:

[Expr(E) || E <- List]

A simple example is as follows:

19> [X+1||X<-[1,2,3,4,5]].[2,3,4,5,6]
In the list parsing expression, | is used to generate list elements on the left, which is equivalent to the constructor. The right side is composed of a value assignment statement and a Condition Statement, and can only contain a value assignment statement. In fact, list parsing optimizes a local function during compilation without worrying too much about its performance.

Note the following when using list Resolution:

20> [X+1||X<-[1,2,3,4,5]],ok.ok
In the preceding example, erlang optimizes list resolution. If the result of list resolution is obviously not used, the list will not be constructed. Here, adding an OK after list resolution can activate erlang optimization.

Reference: http://blog.csdn.net/mycwq/article/details/32160581

Http://www.erlang.org/doc/efficiency_guide/listHandling.html


-Spec reverse (List1)-> what is List2 when in the source code in erlang?

Should it be @ spec? It is a annotation type used to briefly describe this function. It can be understood as a function definition in C language, but the @ spec annotation of erlang does not point out the data type like the C language. List1, 2 should be the list type, reverse () is used to reverse the list, reverse ([,]) = [,]. When is an assertion followed by an expression. Generally, when is used in a function expression, for example, f (X) when (X = 0)-> 0 end. if X = 0 is true, the return value of function f (X) is 0. I also just learned erlang. Although this language is quite small, it is very powerful. I wonder whether these answers are satisfactory.

Write a function loop in Erlang to specify the number of output texts

The answer comes.
To answer this question, I have gained access to Erlang, a good language.

The Code is as follows: note that the file name is saved as test. erl. Be careful when you end all the codes.

-Module (test ).
-Export ([print_string/1]).

Gen_string (1)->
["AB", integer_to_list (1), "C", "B", integer_to_list (2), "D"];
Gen_string (N) when N> 1->
Gen_string (N-1) + + ["AB", integer_to_list (2 * N-1), "C", "B", integer_to_list (2 * N), "D"].

Print_string (N)->
If
N> 0->
Io: fwrite (gen_string (N )),
Io: nl ();
N = <0->
Io: fwrite ("N must be positive \ n ")
End.

The running result is as follows:

63> c: c (test ).
{OK, test}
64> test: print_string (1 ).
AB1CB2D
OK
65> test: print_string (2 ).
AB1CB2DAB3CB4D
OK
66> test: print_string (3 ).
AB1CB2DAB3CB4DAB5CB6D
OK
67> test: print_string (5 ).
AB1CB2DAB3CB4DAB5CB6DAB7CB8DAB9CB10D
OK
68> test: print_string (-1 ).
N must be positive
OK

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.