erlang的坑
来源:互联网 发布:c语言 面向对象 编辑:程序博客网 时间:2024/05/06 05:55
持续记录erlang中的各种坑以及各种解决方案。入门级别的同学都能说出erlang的优点,但是我们不能忽略erlang的各种缺点,一不小心可能造成大麻烦。
1、计算密集型代码执行瓶颈
Erlang的虚拟机是register based的,性能上和python类似,和c语言大概有7倍的差距。这几乎是公认的事实,虽然大部分的集群和网络服务器,性能瓶颈在IO上面,而且这块erts(erlang运行期系统)做的非常的强大,但是一旦涉及到大量的计算,就有点麻烦了。纠结其根本原因,是从字节码到机器码这一部分。和java一样,一段erlang代码,先编译成字节码.beam文件(java里是.class)文件,在运行代码的时候,再根据不同的操作系统由虚拟机编译成相应的机器码(这一点貌似JVM比EVM强大)。java中有jit这样强大的支持,可以把转化机器码这部分的时间缩小,erlang呢?
在遇到计算密集型的需求时,通常的做法是nif,port。这两种机制原理差不多,用之前需要注意一下几点:
(1)确保C代码准确无误并且没有任何异常,否则后果就是整个节点挂掉。
(2)确保C代码没有耗时的操作,否则整个调度器将不能执行其他代码。(即执行nif时,其reduction不会改变,抢占不会发生,尽管我们可以使用一些方法bif中的trap机制,nif中增加reduction的方法,还可以用erlang:system_monitor监控这些方法来控制让出调度器,但是这些的开发成本很大)
如果对自己C代码功底怀疑,nif慎用。其他稳定高效的方法?hipe以及其加强版llvm(有些CPU不支持)。编译时加上native参数即可,例如c(test, [native, {hipe, [to_llvm]}]).
2、list的效率
Erlang的list是最经常使用的一种数据结构,很多操作是基于遍历list来实现的,但是效率呢?10W数量的一个List遍历一次耗时30ms左右,难以接受。其他替代数据结构?
array:可以认为是一个能动态扩展的数组,取值——O(1),插入——O(1),遍历——比list好(越是稀疏的array越好)。
dict:dict是这样一个东西,他有一个segments,包含了所有dict数据(数据就是Key, Value}键值对),segments实际上就是一个tuple,这个segments的每一项是一个segment,segment就是长度为16的tuple(为什么是16,因为源码宏定义死的。。),segment的每一项是一个长度为3的list,list中的每个元素就是一个键值对了。如何决定一个{key, value}在segment的位置?根据erlang:phash(key, 16)的返回结果确定,如果某个位置的key超过3个怎么办?放到下一个segment。由此可以判断其效率,取值——O(1),插入——O(1),遍历——和list没区别(甚至比list要差)。
orddict:和dict完全是两个东西,其实就是一个排好序的tuplelist。所以取值——O(n),插入——O(n),遍历——和list一样。
gb_sets && gb_trees:这两种其实是一个东西,平衡二叉树实现,不同的是gb_sets可以存储任意数据,gb_trees只适合{key, value}结构数据。所以取值——O(logN),插入——O(logN),遍历——和list一致。
sets && ordsets:分别对应dict和orddict,不同的是,他们可以存储任意数据。
从erlang的各种数据类型可以看出,无论何种数据结构,遍历都是一种耗时的操作,所以尽量避免遍历操作可以提升代码效率,另外无论何种数据结构都没有提供复杂的排序方案,没有复杂的取值和插入方法,所以在现实应用中,基本上还是根据当时的具体应用环境用list和tuple两种基础结构来自定义具体的数据结构。
http://blog.yufeng.info/archives/2688
- erlang的坑
- Erlang,优秀的Erlang
- erlang 坑
- erlang lists:keyfind的一个小坑
- [Erlang]Erlang的干将莫邪:Rebar的使用
- [Erlang 0008] Erlang的Match specifications
- [Erlang 0032] Erlang Binary的内部实现
- Erlang学习:介绍Erlang里的Record
- [Erlang]erlang与php的通信
- [Erlang]Erlang与C的节点通信
- [Erlang]通用的erlang优化设置
- Core Erlang:Erlang的Core中间表示
- 进入erlang的世界
- Erlang 的Socket编程
- 进入Erlang的世界
- erlang的哲学
- Erlang节点的连接
- Erlang的最大优势
- java hashcode和equal总结
- C++实现简单选择排序
- iOS —— SQLite3 参数绑定和重执行已编译语句 (二)
- Mysql创建新用户方法
- 高斯混合模型学习笔记
- erlang的坑
- Linux搭建NTP时间服务器
- Web Storage
- 产品成长三步曲
- Aix6.1 安装 Bash Shell环境
- Object-C Swift C++代码相互调用。
- tableview中的一些小问题解决
- iOS开发 cordva 使用 报错信息
- 人脸表情识别综述