* 确保没有任何编译警告



* Erlang中String采用list实现,32位系统中,其1个字符用8个字节的空间(4个保存value, 4个保存指针)。因此string速度较慢,空间占用较大



* 在Server中,总是尽力书写尾递归(tail-recursive)的函数



* 使用'++'时,left list会被拷贝,然后添加到right list的头部,因此最好把length较短的list放在左侧



* 避免使用regexp,如果需要正则表达式,请使用re



* timer模块的大部分函数实现,依赖于一个process,如果过多使用timer,会导致这个process负载过大,影响效率。

  推荐使用erlang:send_after/3及erlang:start_timer/3



* 避免使用list_to_atom/1,因为erlang中atom数量最大为1048576, 且不进行GC控制。因此如果持续性的调用list_to_atom/1

  可能很容易达到系统上限,从而导致emulator terminate。请使用list_to_existing_atom/1。



* list内部实现为一个列表,因此length(List), 需要遍历整个list比较耗时



* 对于不同的数据类型,使用不同的size函数:tuple_size/1, byte_size/1, bit_size/1



* 使用binary match来进行binary的分割,而不使用split_binary/2



* 如果两个list都拥有很多数据,那么请不要使用'--',而是将数据转化到ordsets,然后调用ordsets:substract/2.



* 对于binary相关操作可以进行binary优化(bin_opt_info编译选项)代码框架:



*   f(<<Pattern1,...,Rest/bits>>,...) ->  

       ... % Rest is not used here  

       f(Rest,...);  

    f(<<Pattern2,...,Rest/bits>>,...) ->  

      ... % Rest is not used here  

      f(Rest,...);  

    ...  

    f(<<>>, ...) ->  

      ReturnValue.



* 调用lists:flatten/1可以将list扁平化,这个操作代价很大,比'++'还要昂贵。下面这些时候我们可以避免:

    将数据发送给port时

    调用list_bo_binary/1和iolist_to_binary前



* 小的函数可以让您方便的找出错误的函数和代码



* 不要在同一行出现相同的符号

20    some_fun() ->

21       L = [{key1, v1}, {key2, [some_record#v21, v22]}],

22      ...

编译时,会提示line 21 '[' 语法错误, 因为21行有多个 '[' ,所以这个bug不能准确定位,你需要花时间去排查代码。

好的做法是:

20 some_fun() ->

21      L = [{key1, v1},

22            {key2, [some_record#v21, v22]}

23            ],

      ...

这样,编译其会提示你 line 22 '[' 语法错误,你很开就知道是那个地方错了。



* 使用 CTRL + \ 或 init:stop(), 可以退出Erlang, 使用CTRL + G 及 CTRL + C 弹出菜单选项,可以选择是否退出Erlang。

其中CTRL + G可以用来连接其他的shell, CTRL + C可以查看其他一些系统信息

Ctrl + C abort 是野蛮的退出方式



* 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         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



* 通过code:clash/0 检测代码中是否有module冲突现象(sticky)



* epmd -d -d 启动 epmd 可以查看erlang node之间的通讯



* 将正常的逻辑代码和错误处理代码分离,发生错误时,尽管错误。由另一个错误处理模块进行处理



* 类似于操作系统,我们的程序也可以分为kernel 和 user 两层, 对于kernel绝对不能出现错误, 对于user可以出现错误,进行恢复



* process顶层loop涉及的代码及函数,最好在一个module中实现



* process 的register name和module名称一致, 便于寻找代码



* 每个process具有一个单一的角色,比如:supervisor 用来进行错误恢复, work 工作者,可以出现错误, trusted worker 不会出现错误



* 通过函数调用可以实现的功能,就不要使用sever实现(如gen_server, 及类似的loop 实现)



* 给消息加一个tag,在发生错误的时候,可以定位到消息,同时也有利于程序的稳健



* 在消息循环中,对于unknown的消息,请调用lib:flush_receive/0 将其清除,减轻process msg queue的长度



* server中总是书写尾递归的循环



* 尽量使用record, 而不是原始的tuple来表现数据结构, 在使用record时,使用select match:

#person{name = Name, age = Age} = Person



* 对于返回值,最好也添加一个tag,用来说明返回值类型,或者执行成功与否



* 尽可能少的使用catch和try,在erlang程序中,不推荐主动捕获异常。只有当我们的逻辑特别复杂,我们可以使用throw来返回数据,使用catch来获取返回值。



* 当然程序与外界交互,外界数据不可靠时,需要使用catch和try



* 慎重使用process dictory, 当你使用get/1, put/1时,你的应用会具有很大的slide effect。可以通过加入一个新的参数来保存原本需要存储到process dictory中数据



* 如果不想使自己糊涂,请不要使用import



* 使用export时,将功能类似的接口组合在一起,并添加合理的注视,这样你的接口更清晰,别人使用起来更方便



* 不要书写嵌套太深的代码



* 不要书写太长的module



* 不要书写太长的函数



* 每行代码不能太长



* 避免使用 "_" 匿名变量,请为每个变量选择有意义的名称,如够某个变量暂时不使用,请以下划线 "_" 开始



* {error, enfile} enfile error in socket 是以为内linux系统中 ulimit 限制, 在root下修改:ulimit -n 25000



* {error, enotconn} 表示socket已经关闭



* 在erlang开发时,慎重使用macro,因为erlang的single assign的缘故,同时调用某个marco,而macro又定义了某个变量,可能导致badmatch错误。

比如:

-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)).

如果连续使用 WARN, 会出现此错误



* erlang中可以定义很多环境变量:

ERL_MAX_ETS_TABLES 设置最大的ets数目 默认1400

ERL_MAX_PORTS erlang最大的port数目 默认1024



* .app文件中的start_phases, 选项既可以用来作为include applications之间的同步启动,也可以用来对单个application进行分布启动。

顺序如下

包含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



无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



* 任何时候,都要重视函数的返回值,通过match确保您的预期,如果发生错误,那么就大胆的表达出来。

erlang 开发建议的更多相关文章

  1. 转载:如何利用Vim进行Erlang开发

    转自:http://ovalpo.info/how_to_use_vim_for_erlang_dev/ 如何利用Vim进行Erlang开发 by Martin J. Logan on Septemb ...

  2. 从" ThinkPHP 开发规范 "看 PHP 的命名规范和开发建议

    稍稍水一篇博客,摘抄自Think PHP 的开发规范,很有引导性,我们可以将这些规范实践到原生 PHP 中. 命名规范 使用ThinkPHP开发的过程中应该尽量遵循下列命名规范: 类文件都是以.cla ...

  3. ubuntu 搭建Erlang开发环境

    首先,打好库: sudo apt-get install build-essential sudo apt-get install libncurses5-dev sudo apt-get insta ...

  4. RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue )协议的开源实现。

    RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue )协议的开源实现. 1. 介绍 RabbitMQ是一个由erlang开发的基于AMQP(Advan ...

  5. .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)——转载

    原文链接:https://blog.walterlv.com/post/dotnet-high-performance-reflection-suggestions.html ***** 大家都说反射 ...

  6. intellij ideal 在erlang 开发环境遇到的一些小问题

    由于之前重装电脑,公司电脑上的erlang开发环境重新搭建了,但是由于导入项目错误,直接将项目删掉重新又导入了一次,但是发现使用的sdk在联想输入方面出现了问题,写个东西记一下自己犯的错误. 修正方法 ...

  7. CentOS 6安装thrift支持erlang开发

    早前,在我的博文thrift多平台安装介绍了如何在debian/ubuntu下面安装thrift,并支持erlang开发的.而在CentOS平台下,并没有成功安装.经过不断摸索,终于成功了,这篇博文就 ...

  8. 原 .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)

    大家都说反射耗性能,但是到底有多耗性能,哪些反射方法更耗性能:这些问题却没有统一的描述. 本文将用数据说明反射各个方法和替代方法的性能差异,并提供一些反射代码的编写建议.为了解决反射的性能问题,你可以 ...

  9. Android IOS WebRTC 音视频开发总结(三二)-- WebRTC项目开发建议

    本文主要介绍WEBRTC开发过程中的一些现象,文章来自博客园RTC.Blacker,支持原创,欢迎关注微信公众号blacker,更多详见www.rtc.help 随着移动互联网和智能硬件的快速发展,音 ...

随机推荐

  1. Pregel Worker

  2. Windows server 2016 / Windows 10关于域管理员帐号权限不足的问题

    今天在测试windows server 2016的域创建时,当安装结束之后,发现使用Administrator用户进行操作时,被提示了权限不足这个问题.于是我在百度上查找了一番之后,找到了解决方法. ...

  3. java拷贝--clone

    大纲: java如何拷贝对象. 浅拷贝 深拷贝 一.java如何拷贝对象 Person p = new Person(); Person p2 = p; 上例并不是一个拷贝操作,只是把p对象的引用赋给 ...

  4. 关于使用vue-router的嵌套路由的命名路由时踩的坑

    今天在做我的模仿微博项目时,我想实现点击router-link后,跳转到微博正文页面,并渲染其嵌套视图-评论组件.但是在实际实现时,我发现页面可以正常跳转,但是在页面加载后,并不渲染该页面的嵌套视图, ...

  5. Dart编程布尔值

    Dart为布尔数据类型提供内置支持.Dart中的布尔数据类型仅支持两个值true和false.关键字bool用于表示DART中的布尔值. 在dart中声明布尔变量的语法如下所示 bool var_na ...

  6. PHP headers_sent() 函数

    定义和用法 headers_sent() 函数检查 HTTP 报头是否发送/已发送到何处. 如果报头已发送,该函数返回 TRUE,否则返回 FALSE. 语法 headers_sent(file,li ...

  7. Delphi全面控制Windows任务栏

    使用Windows95/NT/98操作系统的用户知道:Windows正常启动后,在电脑屏幕下方出现一块 任务栏.从系统功能角度而言,整个任务栏包括几个不同的子区域,从左至右依次是:开始 按钮.应用程序 ...

  8. 理解MITRE ATT&CK矩阵

    最近准备学习一下关于ATT&CK的知识,这里面先来理解一下什么是ATT&CK(通过对ATT&CK的学习,可以很快的对安全领域有一个比较全面的认识). 什么是MITRE MITR ...

  9. 浅谈使用RestKit将服务器的Json直接映射为本地对象

    RestKit是一个主要用于iOS上网络通信的开源框架,除了发送请求与接受响应这些基本功能外,还附带coredata,以及将远程JSON映射为本地对象的功能.目前版本0.9.3,coredata还不是 ...

  10. hdu多校第一场1004(hdu6581)Vacation 签到

    题意:有n+1辆车,每辆车都有一定的长度,速度和距离终点的距离,第1-n辆车在前面依次排列,第0辆车在最后面.不允许超车,一旦后车追上前车,后车就减速,求第0辆车最快什么时候能到达终点? 思路:对于每 ...