`
mryufeng
  • 浏览: 982359 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

per module constant pool 调查和使用

阅读更多
原文地址 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, 无需创建,无需拷贝,这就是它的意义!













分享到:
评论
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.
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.

呵呵,不断变化中...

相关推荐

    ASN.1PER编码方式以及测试程序

    在PER编码中,这些数据类型会根据其值域和实际值进行优化编码,以减少存储和传输时的字节使用。例如,小的整数可能只需要一两个位来表示,而大整数则会使用更长的位串。对于字符串,PER会尽可能地进行长度编码,避免...

    Per1编程24学时教程

    4. **字符串和正则表达式**:Per1在处理文本和字符串方面非常强大,你会学习如何使用字符串方法、正则表达式进行文本操作和匹配,这对于很多实际应用至关重要。 5. **文件和I/O操作**:了解如何打开、读取、写入和...

    nginx限制连接数ngx_http_limit_conn_module模块1

    【Nginx 限制连接数 ngx_http_limit_conn_module 模块详解】 在互联网服务中,服务器经常面临流量异常、负载过大的情况,尤其在遭受大流量恶意攻击时,带宽的...正确配置和使用该模块对于保障网站安全和性能至关重要。

    wcf 通信模型 percall persession single 很好的例子

    本示例主要涵盖了三种通信模型:PerCall、PerSession和Single。 **1. PerCall模型** PerCall模型是最常见的服务实例化策略。在每次客户端调用服务操作时,都会创建一个新的服务实例来处理该请求,然后在操作完成后...

    asn per压缩编码规则说明

    - **物联网(IoT)**:在物联网设备中,由于计算资源和能源的限制,采用PER编码可以优化数据处理和存储。 #### 五、结语 **ASN.1 PER压缩编码规则**是数据编码领域的一项重要技术,它不仅提高了数据传输的效率,还...

    Asn.1编解码动态库 支持Ber/Per

    Ber和Per编码规则提供了在不同环境下的灵活性和效率,而提供的实例和例程则有助于开发者快速上手,有效地集成到自己的项目中。通过深入理解和熟练运用这个库,开发者可以构建出符合标准且高效的通信系统或软件。

    ASN-PER编码规范.pdf

    3GPP 的规范中,由 ASN.1 到传输码的转换统一使用定义在 ITU-T X.691 中的 PER (Packed Encoding Rules)规则,因此这里讲的 ASN 编译码规则也就是 ASN 编码中的 PER 编译码规则。 PER 有两个变体:对齐方式和非对齐方...

    Getting Started with OpenCart Module Development

    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和oer编码规则)

    ASN.1:抽象标记语言 PER:压缩编码规则(Packed Encoding Rules),ASN.1编码规则之一 OER: 八位字节编码规则(Specification of Octet Encoding Rules),ASN.1编码规则之一

    ib_fmr_pool.rar_Creating

    `ib_fmr_pool`是用于创建和管理FMR池的接口,其相关知识点包括以下内容: 1. **FMR(Fast Message Register)**:FMR是InfiniBand Verbs(IBV)的一部分,它提供了一种高效的数据传输机制。通过FMR,应用程序可以...

    GLSL的per_pixel shading

    你可以创建一个简单的3D场景,比如一个球体或立方体,然后分别用per_vertex和per_pixel shading进行渲染。观察并分析两种方法下的光照、纹理和阴影的表现。同时,你还可以考虑性能因素,看看在不同的硬件配置下,哪...

    多久才能拥有100万(一)_Excel期数函数NPER的应用.rar

    通过这个案例,我们不仅学习了如何使用NPER函数,还了解了如何处理年利率与月利率之间的转换,以及在财务计算中如何考虑现值和未来值。在实际工作和生活中,这样的计算技巧对于个人理财规划和投资决策是非常有帮助的...

    Per.js v3.0.zip

    阅读这份文档将有助于我们快速熟悉Per.js的功能和使用方法,从而高效地利用这个工具。 总的来说,"Per.js v3.0.zip"提供的资源对于学习JavaScript编程、理解源码设计、进行项目实践和研究都具有很高的价值。无论是...

    ubuntu20.04安装aper-笔记

    在日常使用中,定期更新Aper以获取最新的功能和修复是非常重要的。你可以通过运行`sudo apt upgrade aper`来实现这一点。 请注意,这里提到的`ruc_master_paper-master (6).zip`文件可能包含了一个与Aper相关的论文...

    ACCA PER Challenge-示例参考

    ACCA PER(Practical Experience Requirements)参考用,建议先参考这个案例写好再复制进官网的各个问题栏里。文档涵盖了以下几个PER:01,03,04,05,08,10,13,15,17,19.

    hibernate Table per class hierarchy 例子代码

    在Java的持久化框架Hibernate中,"Table per Class Hierarchy"是一种继承映射策略,它在数据库层面将类继承关系转换为单一表的结构。...你可以通过研究这些代码来更好地理解和应用"Table per Class Hierarchy"策略。

    Per.js v3.0-源码.zip

    按照提示访问www.cqlsoft.com,可以获取更多关于Per.js的文档和更新信息,对于学习和使用Per.js会有很大帮助。 总的来说,Per.js v3.0的源码学习是一次深入理解JavaScript库设计和实现的好机会。通过这次学习,你...

    percpu-km.rar_V2

    总之,`percpu-km.rar_V2`这个压缩包中的内容是关于Linux内核如何使用percpu内存分配来提高多处理器系统性能的重要资料。通过深入研究`percpu-km.c`源码,不仅可以增强对Linux内核内存管理的理解,还能为系统优化和...

    die per wafer_assignmentproblem_siliconcrystal_assignment_

    标题中的"die per wafer_assignmentproblem_siliconcrystal_assignment_"暗示了我们正在讨论半导体制造中的一个关键问题,即晶圆上的芯片分配问题。在集成电路(IC)制造中,晶圆是制造微小电子器件的基本平台,而...

Global site tag (gtag.js) - Google Analytics