The following are some records in Erlang project development, including many easy-to-understand principles, and some plausible suggestions, which are confusing and have not yet accumulated to the point where they can be categorized, let's take a look ..
* Make sure there are no compilation warnings
* In Erlang, string is implemented by list. In 32-bit systems, the space of one character is 8 bytes (four values are saved and four pointer values are saved ). Therefore, the string speed is slow and the space usage is large.
* On the server, you always try your best to write tail-recursive functions.
* When '+ +' is used, the left list will be copied and added to the right list header. Therefore, it is best to place the list with a shorter length on the left.
* Avoid using Regexp. If you need a regular expression, use re
* Most of the functions of the timer module depend on a process. If timer is used too much, the load of the process is too large, which affects the efficiency.
We recommend that you use Erlang: send_after/3 and Erlang: start_timer/3.
* Do not use list_to_atom/1 because the maximum number of atom in Erlang is 1048576, and GC control is not performed. Therefore, if you call list_to_atom/1 continuously
Emulator terminate may easily be reached. Use list_to_existing_atom/1.
* The list is implemented as a list, so length (list) requires time to traverse the entire list.
* For different data types, use different size functions: tuple_size/1, byte_size/1, bit_size/1
* Binary match is used for Binary Division, instead of split_binary/2.
* If both lists have a lot of data, do not use '--'. Instead, convert the data to ordsets and call ordsets: substract/2.
* Binary-related operations can be optimized (bin_opt_info compilation option) by using the code framework:
* F (<pattern1,..., rest/bits>,...)->
... % Rest is not used here
F (rest ,...);
F (<pattern2,..., rest/bits>,...)->
... % Rest is not used here
F (rest ,...);
...
F (<>,...)->
Returnvalue.
* Calling lists: flatten/1 can flat the list, which is more expensive than '++. We can avoid the following:
When sending data to the port
Before calling list_bo_binary/1 and iolist_to_binary
* Small functions allow you to easily find out wrong functions and codes.
* Do not use the same symbol in the same line.
20 some_fun ()->
21 L = [{key1, V1}, {key2, [some_record # V21, v22]}],
22...
During compilation, line 21 '[' syntax error will be prompted. Because line 21 has multiple '[', this bug cannot be accurately located. You need to spend time investigating the code.
A good practice is:
20 some_fun ()->
21 L = [{key1, V1 },
22 {key2, [some_record # V21, v22]}
23],
...
In this way, the compilation will prompt you line 22 '[' syntax error. You can easily find out where it is wrong.
* Use Ctrl +/or init: Stop () to exit Erlang. use Ctrl + G and CTRL + C to display the menu options. You can choose whether to exit Erlang.
CTRL + G can be used to connect to other shells. CTRL + C can be used to view other system information.
CTRL + C abort is a brutal exit Method
* Use "open_port ({FD, 0, 2}, [out])" make Erlang program write standard error to UNIX System
* If you don't run experiments before you start designing a new system, your entire system will be an experiment!
* Standard data structure Desc:
Module description
Sets, I. e. A collection of unique elements.
Gb_sets sets, but based on a general balanced Data Structure
Gb_tree a general balanced tree
Dict maps, also called associative arrays
ETS hash tables and Ordered Sets (trees)
Dets on-disk hash tables
Suggestion:
Elments count: 0-100 | 100-10000 | 10000-
Our select: List | ETS | gb_tree
* Check whether there is a module conflict (sticky) in the Code through code: clash/0)
* Start EPMD-D-d to view the communication between Erlang nodes.
* Separates the normal logic code from the error handling code. When an error occurs, it is ignored. Handled by another error handling module
* Similar to the operating system, our programs can be divided into two layers: kernel and user. There is no error in kernel, and errors can be made to users for recovery.
* The code and functions involved in the top-layer loop of process are best implemented in a module.
* The register name of process is the same as the module name to facilitate code search.
* Each process has a single role, for example, the supervisor is used for error recovery, and the work worker may have errors. Trusted worker will not have errors.
* Do not use sever to implement functions that can be implemented through function calls (such as gen_server and similar loop implementations)
* Add a tag to the message. When an error occurs, the message can be located, which also facilitates program stability.
* In a message loop, call Lib: flush_receive/0 to clear unknown messages to reduce the length of process MSG queue.
* The server always writes tail recursion cycles.
* Try to use record instead of the original tuple to represent the data structure. When using record, use select match:
# Person {name = Name, age = age} = person
* It is recommended that you add a tag to indicate the type of the returned value or whether the execution is successful.
* Catch and try are used as few as possible. In Erlang programs, it is not recommended to actively catch exceptions. Only when our logic is particularly complex can we use throw to return data and catch to get the return value.
* Of course, when the program interacts with the outside world and the external data is unreliable, use catch and try.
* Use process dicloud with caution. When you use GET/1, put/1, your application will have a large slide effect. You can add a new parameter to save the data originally stored in process dictory.
* If you do not want to confuse yourself, do not use import
* When using export, combine functional interfaces and add a reasonable look, so that your interfaces are clearer and easier to use.
* Do not write code with too deep nesting
* Do not write too long modules.
* Do not write functions that are too long.
* Each line of code cannot be too long.
* Avoid using "_" anonymous variables. Please select a meaningful name for each variable. If a variable is not used for the time being, start "_".
* {Error, enfile} enfile Error
In socket refers to the ulimit limit in Linux, which can be modified under root: ulimit-N 25000
* {Error, enotconn} indicates that the socket has been closed.
* When developing Erlang, use macro with caution. Because of Erlang's single assign, a Marco is called at the same time, while macro defines a variable, which may cause badmatch errors.
For example:
-Define (addlineinfo1 (f ),
(
Begin
Str1 = lists: Concat (["Mod :",? Module, "line :",? Line, "]"]),
Str1 ++ F
End
)).
-Define (warn (log, F, d), log4erl: Warn (log ,? Addlineinfo (F), d )).
This error occurs if you use warn consecutively.
* Many environment variables can be defined in Erlang:
Erl_max_ets_tables: sets the maximum number of ETS. The default value is 1400.
Erl_max_ports the maximum number of ports in Erlang is 1024 by default.
*. Start_phases in the app file. The options can be used for Synchronous start between include applications or distributed start of a single application.
The order is as follows:
Contains the extended app:
Application: Start (prim_app)
=> Prim_app_cb: Start (normal, [])
=> Prim_app_cb: start_phase (init, normal, [])
=> Prim_app_cb: start_phase (go, normal, [])
=> Incl_app_cb: start_phase (go, normal, [])
OK
No supported ded app:
Application: Start (prim_app)
=> Prim_app_cb: Start (normal, [])
=> Prim_app_cb: start_phase (init, normal, [])
=> Prim_app_cb: start_phase (go, normal, [])
OK
*
At any time, pay attention to the return value of the function, and ensure your expectation through match. If an error occurs, express it boldly.
From: http://blog.csdn.net/zhangxinrun/article/details/6399062