- 浏览: 982359 次
- 性别:
- 来自: 广州
最新评论
-
qingchuwudi:
有用,非常感谢!
erlang进程的优先级 -
zfjdiamond:
你好 这条命令 在那里输入??
你们有yum 我有LuaRocks -
simsunny22:
这个是在linux下运行的吧,在window下怎么运行escr ...
escript的高级特性 -
mozhenghua:
http://www.erlang.org/doc/apps/ ...
mnesia 分布协调的几个细节 -
fxltsbl:
A new record of 108000 HTTP req ...
Haproxy 1.4-dev2: barrier of 100k HTTP req/s crossed
原文地址 http://noss.github.com/2009/04/02/constant-pool-erlang-hack.html
2009-04-02
Erlang R12B-0 added a per-module memory area for constants, the literal values in a module are stored there. Before, they were allocated on the heap every time they were referenced. This meant that some kinds of optimization that avoided literal lookup-tables became irrelevant in one go (without even recompiling the source). A great example of the kind of improvements that OTP focus on: removing speed-bumps to having beautiful code.
From the release notes of R12B-0
OTP-6850: Literal lists, tuples, and binaries are no longer constructed at run-time as they used to be, but are stored in a per-module constant pool. Literals that are used more than once are stored only once.
This is not a change to the language, only in the details of its implementation. Therefore, the implications of this change is described in the Efficiency Guide.
The erlang efficiency guide on constant pools pretty much say the same thing. But Björn Gustavsson adds this very interesting remark about unloading a module and the constant pool.
If one has very assymetric access patterns to some value, Maybe millions of times more reads than updates, and this is a measured problem, one can reach for hacks such as generating a module containing the values as literals and thus have a global configuration value that will not grow your heap unecessary.
But…
As always, remember when to optimize.
-------------------------------------------------------------------------
在对beam_load.c:read_literal_table(LoaderState* stp)函数打了补丁 显示出这个模块的literal数目和类型我们可以看到这样的结果:
module base64: num_literals[4]
0: tag[1], size[5], term["="]
1: tag[1], size[6], term["=="]
2: tag[3], size[131], term[{65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47}]
3: tag[3], size[1086], term[{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}]
这个是标准库base64.erl的literal.
从统计可以看出 atom本身已经不是literal, 这里大部分的literal是1,3的类型也是据说是tuple和list, 0是代表binary.
你在程序里面形如:
[1,2,3,4].
{1,2,3,4}.
<<1,2,3,4>>.
的编译器常量就会被放在模块的literal表格里面 在beam加载的时候 这些常量就创建完毕在内存里,同时调整涉及这些常量的模块的op code,让它们直接使用这些常量,而不是每次新建一个。
这样的优化对于base64或者c程序出身的人很有帮助,应为我们最擅长查表格,常数的查询时间。那么现在我们也可以在erlang下这么用了,看下base64.erl代码
%% arrays for character translation
%% value -> base64 (zero-based)
encode_tuple() ->
{$A, $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N,
$O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z,
$a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, $n,
$o, $p, $q, $r, $s, $t, $u, $v, $w, $x, $y, $z,
$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $+, $/}.
%% base64 -> value (one-based)
decode_tuple() ->
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}.
%% accessors
b64e(X, T) ->
element(X+1, T).
b64d(X, T) ->
b64d_ok(element(X, T)).
-spec b64d_ok(non_neg_integer()) -> non_neg_integer().
b64d_ok(N) when N >= 0 ->
N.
舒服吧! 很多时候如果你的erl程序设计到常量的问题 有效率问题的时候 你可以动态生成一个erl文件然后用编译器编译再动态加载,最大程度的提高效率。 你的这些常量不参与GC, 无需创建,无需拷贝,这就是它的意义!
2009-04-02
Erlang R12B-0 added a per-module memory area for constants, the literal values in a module are stored there. Before, they were allocated on the heap every time they were referenced. This meant that some kinds of optimization that avoided literal lookup-tables became irrelevant in one go (without even recompiling the source). A great example of the kind of improvements that OTP focus on: removing speed-bumps to having beautiful code.
From the release notes of R12B-0
OTP-6850: Literal lists, tuples, and binaries are no longer constructed at run-time as they used to be, but are stored in a per-module constant pool. Literals that are used more than once are stored only once.
This is not a change to the language, only in the details of its implementation. Therefore, the implications of this change is described in the Efficiency Guide.
The erlang efficiency guide on constant pools pretty much say the same thing. But Björn Gustavsson adds this very interesting remark about unloading a module and the constant pool.
If one has very assymetric access patterns to some value, Maybe millions of times more reads than updates, and this is a measured problem, one can reach for hacks such as generating a module containing the values as literals and thus have a global configuration value that will not grow your heap unecessary.
But…
As always, remember when to optimize.
-------------------------------------------------------------------------
在对beam_load.c:read_literal_table(LoaderState* stp)函数打了补丁 显示出这个模块的literal数目和类型我们可以看到这样的结果:
module base64: num_literals[4]
0: tag[1], size[5], term["="]
1: tag[1], size[6], term["=="]
2: tag[3], size[131], term[{65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47}]
3: tag[3], size[1086], term[{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}]
这个是标准库base64.erl的literal.
从统计可以看出 atom本身已经不是literal, 这里大部分的literal是1,3的类型也是据说是tuple和list, 0是代表binary.
你在程序里面形如:
[1,2,3,4].
{1,2,3,4}.
<<1,2,3,4>>.
的编译器常量就会被放在模块的literal表格里面 在beam加载的时候 这些常量就创建完毕在内存里,同时调整涉及这些常量的模块的op code,让它们直接使用这些常量,而不是每次新建一个。
这样的优化对于base64或者c程序出身的人很有帮助,应为我们最擅长查表格,常数的查询时间。那么现在我们也可以在erlang下这么用了,看下base64.erl代码
%% arrays for character translation
%% value -> base64 (zero-based)
encode_tuple() ->
{$A, $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N,
$O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z,
$a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, $n,
$o, $p, $q, $r, $s, $t, $u, $v, $w, $x, $y, $z,
$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $+, $/}.
%% base64 -> value (one-based)
decode_tuple() ->
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}.
%% accessors
b64e(X, T) ->
element(X+1, T).
b64d(X, T) ->
b64d_ok(element(X, T)).
-spec b64d_ok(non_neg_integer()) -> non_neg_integer().
b64d_ok(N) when N >= 0 ->
N.
舒服吧! 很多时候如果你的erl程序设计到常量的问题 有效率问题的时候 你可以动态生成一个erl文件然后用编译器编译再动态加载,最大程度的提高效率。 你的这些常量不参与GC, 无需创建,无需拷贝,这就是它的意义!
评论
2 楼
mryufeng
2009-09-04
>> As far as I know, these constants will not be copied to the private
>> heaps of the processes.
>
> You're talking about current Erlang releases, right? How does that
> work with module reloading? E.g., if foo:bar/0 returns a constant
> complex data structure and the result is not copied into the calling
> process's private heap, what happens when a module is purged while a
> process is still holding onto a reference to the data structure?
The data will be copied to the heap of each process that has a reference
to the data before the module is purged.
>> heaps of the processes.
>
> You're talking about current Erlang releases, right? How does that
> work with module reloading? E.g., if foo:bar/0 returns a constant
> complex data structure and the result is not copied into the calling
> process's private heap, what happens when a module is purged while a
> process is still holding onto a reference to the data structure?
The data will be copied to the heap of each process that has a reference
to the data before the module is purged.
1 楼
litaocheng
2009-05-13
老大在孜孜不倦的发现erlang的精妙之处哈哈。
引用:http://www.erlang.org/doc/efficiency_guide/processes.html#8.2
里面的描述:
8.2.1 The constant pool
Constant Erlang terms (also called literals) are now kept in constant pools; each loaded module has its own pool, constant terms will no longer build the tuple every time it is called.
But if a constant is sent to another process (or stored in an ETS table), it will be copied.
The copying of constants might be eliminated in a future release.
呵呵,不断变化中...
引用:http://www.erlang.org/doc/efficiency_guide/processes.html#8.2
里面的描述:
8.2.1 The constant pool
Constant Erlang terms (also called literals) are now kept in constant pools; each loaded module has its own pool, constant terms will no longer build the tuple every time it is called.
But if a constant is sent to another process (or stored in an ETS table), it will be copied.
The copying of constants might be eliminated in a future release.
呵呵,不断变化中...
发表评论
-
OTP R14A今天发布了
2010-06-17 14:36 2677以下是这次发布的亮点,没有太大的性能改进, 主要是修理了很多B ... -
R14A实现了EEP31,添加了binary模块
2010-05-21 15:15 3030Erlang的binary数据结构非常强大,而且偏向底层,在作 ... -
如何查看节点的可用句柄数目和已用句柄数
2010-04-08 03:31 4814很多同学在使用erlang的过程中, 碰到了很奇怪的问题, 后 ... -
获取Erlang系统信息的代码片段
2010-04-06 21:49 3475从lib/megaco/src/tcp/megaco_tcp_ ... -
iolist跟list有什么区别?
2010-04-06 20:30 6529看到erlang-china.org上有个 ... -
erlang:send_after和erlang:start_timer的使用解释
2010-04-06 18:31 8386前段时间arksea 同学提出这个问题, 因为文档里面写的很不 ... -
Latest news from the Erlang/OTP team at Ericsson 2010
2010-04-05 19:23 2013参考Talk http://www.erlang-factor ... -
对try 异常 运行的疑问,为什么出现两种结果
2010-04-05 19:22 2842郎咸武<langxianzhe@163.com> ... -
Erlang ERTS Async基础设施
2010-03-19 00:03 2517其实Erts的Async做的很不错的, 相当的完备, 性能又高 ... -
CloudI 0.0.9 Released, A Cloud as an Interface
2010-03-09 22:32 2476基于Erlang的云平台 看了下代码 质量还是不错的 完成了不 ... -
Memory matters - even in Erlang (再次说明了了解内存如何工作的必要性)
2010-03-09 20:26 3439原文地址:http://www.lshift.net/blog ... -
Some simple examples of using Erlang’s XPath implementation
2010-03-08 23:30 2050原文地址 http://www.lshift.net/blog ... -
lcnt 环境搭建
2010-02-26 16:19 2614抄书:otp_doc_html_R13B04/lib/tool ... -
Erlang强大的代码重构工具 tidier
2010-02-25 16:22 2486Jan 29, 2010 We are very happy ... -
[Feb 24 2010] Erlang/OTP R13B04 has been released
2010-02-25 00:31 1387Erlang/OTP R13B04 has been rele ... -
R13B04 Installation
2010-01-28 10:28 1390R13B04后erlang的源码编译为了考虑移植性,就改变了编 ... -
Running tests
2010-01-19 14:51 1486R13B03以后 OTP的模块加入了大量的测试模块,这些模块都 ... -
R13B04在细化Binary heap
2010-01-14 15:11 1508从github otp的更新日志可以清楚的看到otp R13B ... -
R13B03 binary vheap有助减少binary内存压力
2009-11-29 16:07 1668R13B03 binary vheap有助减少binary内存 ... -
erl_nif 扩展erlang的另外一种方法
2009-11-26 01:02 3218我们知道扩展erl有2种方法, driver和port. 这2 ...
相关推荐
在PER编码中,这些数据类型会根据其值域和实际值进行优化编码,以减少存储和传输时的字节使用。例如,小的整数可能只需要一两个位来表示,而大整数则会使用更长的位串。对于字符串,PER会尽可能地进行长度编码,避免...
4. **字符串和正则表达式**:Per1在处理文本和字符串方面非常强大,你会学习如何使用字符串方法、正则表达式进行文本操作和匹配,这对于很多实际应用至关重要。 5. **文件和I/O操作**:了解如何打开、读取、写入和...
【Nginx 限制连接数 ngx_http_limit_conn_module 模块详解】 在互联网服务中,服务器经常面临流量异常、负载过大的情况,尤其在遭受大流量恶意攻击时,带宽的...正确配置和使用该模块对于保障网站安全和性能至关重要。
本示例主要涵盖了三种通信模型:PerCall、PerSession和Single。 **1. PerCall模型** PerCall模型是最常见的服务实例化策略。在每次客户端调用服务操作时,都会创建一个新的服务实例来处理该请求,然后在操作完成后...
- **物联网(IoT)**:在物联网设备中,由于计算资源和能源的限制,采用PER编码可以优化数据处理和存储。 #### 五、结语 **ASN.1 PER压缩编码规则**是数据编码领域的一项重要技术,它不仅提高了数据传输的效率,还...
Ber和Per编码规则提供了在不同环境下的灵活性和效率,而提供的实例和例程则有助于开发者快速上手,有效地集成到自己的项目中。通过深入理解和熟练运用这个库,开发者可以构建出符合标准且高效的通信系统或软件。
3GPP 的规范中,由 ASN.1 到传输码的转换统一使用定义在 ITU-T X.691 中的 PER (Packed Encoding Rules)规则,因此这里讲的 ASN 编译码规则也就是 ASN 编码中的 PER 编译码规则。 PER 有两个变体:对齐方式和非对齐方...
This book shows you how to create custom OpenCart modules and pages which are needed as per the requirements of the clients to manage custom data. It describes each and every code used to make a Hello...
ASN.1:抽象标记语言 PER:压缩编码规则(Packed Encoding Rules),ASN.1编码规则之一 OER: 八位字节编码规则(Specification of Octet Encoding Rules),ASN.1编码规则之一
`ib_fmr_pool`是用于创建和管理FMR池的接口,其相关知识点包括以下内容: 1. **FMR(Fast Message Register)**:FMR是InfiniBand Verbs(IBV)的一部分,它提供了一种高效的数据传输机制。通过FMR,应用程序可以...
你可以创建一个简单的3D场景,比如一个球体或立方体,然后分别用per_vertex和per_pixel shading进行渲染。观察并分析两种方法下的光照、纹理和阴影的表现。同时,你还可以考虑性能因素,看看在不同的硬件配置下,哪...
通过这个案例,我们不仅学习了如何使用NPER函数,还了解了如何处理年利率与月利率之间的转换,以及在财务计算中如何考虑现值和未来值。在实际工作和生活中,这样的计算技巧对于个人理财规划和投资决策是非常有帮助的...
阅读这份文档将有助于我们快速熟悉Per.js的功能和使用方法,从而高效地利用这个工具。 总的来说,"Per.js v3.0.zip"提供的资源对于学习JavaScript编程、理解源码设计、进行项目实践和研究都具有很高的价值。无论是...
在日常使用中,定期更新Aper以获取最新的功能和修复是非常重要的。你可以通过运行`sudo apt upgrade aper`来实现这一点。 请注意,这里提到的`ruc_master_paper-master (6).zip`文件可能包含了一个与Aper相关的论文...
ACCA PER(Practical Experience Requirements)参考用,建议先参考这个案例写好再复制进官网的各个问题栏里。文档涵盖了以下几个PER:01,03,04,05,08,10,13,15,17,19.
在Java的持久化框架Hibernate中,"Table per Class Hierarchy"是一种继承映射策略,它在数据库层面将类继承关系转换为单一表的结构。...你可以通过研究这些代码来更好地理解和应用"Table per Class Hierarchy"策略。
按照提示访问www.cqlsoft.com,可以获取更多关于Per.js的文档和更新信息,对于学习和使用Per.js会有很大帮助。 总的来说,Per.js v3.0的源码学习是一次深入理解JavaScript库设计和实现的好机会。通过这次学习,你...
总之,`percpu-km.rar_V2`这个压缩包中的内容是关于Linux内核如何使用percpu内存分配来提高多处理器系统性能的重要资料。通过深入研究`percpu-km.c`源码,不仅可以增强对Linux内核内存管理的理解,还能为系统优化和...
标题中的"die per wafer_assignmentproblem_siliconcrystal_assignment_"暗示了我们正在讨论半导体制造中的一个关键问题,即晶圆上的芯片分配问题。在集成电路(IC)制造中,晶圆是制造微小电子器件的基本平台,而...