http://www.javaeye.com/topic/374167
Here are some of the records in Erlang project development that contain a lot of easy-to-understand principles, as well as some specious suggestions that are confusing and not accumulating to a point where they can be categorized, and you'll see.
:)
* Make sure there are no compilation warnings
* String in Erlang is implemented in a list, with 32-bit systems with 1 characters in 8-byte space (4 holds value and 4 holds pointers). Therefore, the string speed is slow, the space occupies a large
* In server, always try to write the function of tail recursion (tail-recursive)
* When using ' + + ', the left list is copied and added to the head of the right list, so it's best to put a short list
* Avoid using RegExp, if you need regular expressions, use re
* Most functions of the timer module are implemented, depending on a process, if excessive use of the timer, will cause the process load is too large, affecting efficiency.
Recommended use of ERLANG:SEND_AFTER/3 and ERLANG:START_TIMER/3
* Avoid using LIST_TO_ATOM/1 because the maximum number of atoms in Erlang is 1048576 and does not take GC control. So if the persistent call LIST_TO_ATOM/1
The system cap may be easily reached, resulting in emulator terminate. Please use LIST_TO_EXISTING_ATOM/1.
* List is implemented as a listing, so length (list), need to traverse the entire list is more time consuming
* For different data types, use a different size function: TUPLE_SIZE/1, BYTE_SIZE/1, BIT_SIZE/1
* Use binary match to split binary, instead of using SPLIT_BINARY/2
* If two lists have a lot of data, do not use '--', but instead convert the data to Ordsets and call ORDSETS:SUBSTRACT/2.
* Binary Optimization (bin_opt_info compilation option) code framework is available for binary related operations:
* 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 flatten the list, which is expensive to use, and is much more costly than ' + + '. Here are some times we can avoid:
When you send data to port
Before calling LIST_BO_BINARY/1 and Iolist_to_binary
* Small function allows you to easily find the wrong function and code
* Do not show the same symbol on the same line
Some_fun ()
L = [{key1, v1}, {key2, [Some_record#v21, V22]}],
22 ...
At compile time, you will be prompted with line 21 ' [' syntax error, because there are multiple ' [' in 21 rows, so this bug cannot be correctly located and you need to take the time to troubleshoot the code.
The good practice is to:
Some_fun ()
L = [{key1, v1},
{Key2, [Some_record#v21, V22]}
23],
...
In this way, compiling it will prompt you for line 22 ' [' syntax error, you are very open to know that the place is wrong.
* Use CTRL + \ or Init:stop () to exit Erlang, use CTRL + G and CTRL + C pop-up menu options to choose whether to exit Erlang.
Where CTRL + G can be used to connect to other shells, CTRL + C can see some other system information
Ctrl + C Abort is a savage way of quitting
* use ' Open_port ({fd,0,2}, [out] ') ' Make Erlang program write ' Error to UNIX system
* If You don't run experiments before you start designing a new system, your entire system would be a experiment!
* Standard data structure desc:
Module Description
Sets sets, i.e. a collection of unique elements.
Gb_sets sets, but based to 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
* code:clash/0 detect if there is a module conflict in the code (sticky)
* epmd-d-D start EPMD to view communication between Erlang node
* Separate the normal logic code from the error handling code, in the event of an error, despite the error. Handled by another error handling module
* Similar to the operating system, our program can also be divided into kernel and user two layer, for kernel absolutely can not error, for user can error, to recover
* The code and functions involved in the process top loop are best implemented in a module
* The register name and module names of the process are consistent to facilitate the search for code
* Each process has a single role, such as: Supervisor used for error recovery, work worker, can error, trusted worker does not appear error
* Do not use sever implementations (such as Gen_server, and similar loops implementations) with functions that can be implemented by function calls
* To add a tag to the message, in the event of an error, you can locate the message, but also conducive to the robustness of the program
* In the message loop, for unknown messages, call lib:flush_receive/0 to clear them, easing the length of the process msg queue
* The loop of tail recursion is always written in server
* Use the record instead of the original tuple to represent the data structure, using the select match when using the record:
#person {name = name, age = age} = person
* For return values, it is best to also add a tag that describes the return value type, or whether the execution succeeds or not
* Use catch and try as few as possible, and it is not recommended to actively catch exceptions in an Erlang program. Only when our logic is particularly complex, we can use throw to return the data and use catch to get the return value.
* Of course the program interacts with the outside world, when external data is unreliable, you need to use catch and try
* Use process dictory carefully, and when you use GET/1, PUT/1, your app will have a great slide effect. You can save the data that you originally need to store in the process dictory by adding a new parameter
* If you do not want to confuse yourself, please do not use the import
* When using export, combine the functionally similar interfaces and add a reasonable gaze so that your interface is clearer and others are easier to use.
* Do not write code that is too deep to nest
* Do not write too long module
* Don't write too long a function
* Each line of code cannot be too long
* Avoid using "_" Anonymous variables, please select a meaningful name for each variable, such as enough to temporarily not use a variable, please underline "_" Start
* {error, enfile} enfile error in socket is a ulimit limitation within Linux system, modified under root: Ulimit-n 25000
* {error, Enotconn} indicates that the socket is closed
* Use macro sparingly when developing Erlang, because the single assign of Erlang, while calling a Marco while macro defines a variable, can cause Badmatch errors.
Like what:
-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 WARN is used continuously
* Many environment variables can be defined in Erlang:
Erl_max_ets_tables set the maximum number of ETS by default 1400
Erl_max_ports Erlang Maximum number of ports default 1024
*. start_phases in app files, options can be used either as a synchronous start-up between include applications or as a distribution to a single application.
The order is as follows
Include included 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 included 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, ensure your expectations through match, and if there is an error, say it boldly.
Establish an OTP application