如何在Elixir中获取变量的内存位置?

时间:2017-10-21 18:13:56

标签: erlang elixir

我们了解Elixir的事实是data structures that lives in memory are immutable, and variables are just pointers to those data structures

我们是否有办法让变量的内存地址指向,而不是该内存位置的内容(即变量的取消引用值)?

对我来说,这样做的目的是我们可以了解Elixir / Erlang在处理重复值时如何管理内存,例如两个相同的字符列表,或者特别是在tuples and lists may share their contents的某些情况下,并写更多高效的代码。

  

例如,当您更新元组时,除了已替换的条目之外,所有条目都在旧元组和新元组之间共享。换句话说,Elixir中的元组和列表能够共享其内容。

1 个答案:

答案 0 :(得分:12)

TL; DR:

不,你无法获得变量的内存位置。

讨论

原则上一切都被复制了。每个进程都有自己的堆。这就是事情的方式。

实际上有一些潜在的速度黑客攻击。最值得注意的是

  • 编译时已知的文字从全局堆中引用(在某些情况下,这是一个巨大的性能提升)。
  • 从全局堆中引用大于64字节的二进制文件(这也会导致二进制文件成为漏洞抽象,因此binary:copy/1,2)。
  • 对大多数结构的更新实际上并不需要复制整个结构(特别感兴趣的是what goes on inside maps) - 但是随着更多的效率工作进入运行时,需要多少以及何时需要进行复制。
  • 垃圾收集发生每个进程这就是为什么Erlang似乎有一个神奇的高级增量GC方案,但实际上下面有一些相当无聊的世代堆集合(在一般情况下,就是这样;方法是actually somewhat of a hybrid - EVM性能增强不断发展的领域的另一部分......)。

如果您要为EVM编写代码,无论使用何种语言,都应该放弃您将超越运行时的想法。这与完全相同的原因是,试图超越大多数C(尤其是C ++)编译器优化几乎无处不在是一种禁止的做法。

每个主要版本都包含一些新实施的性能增强功能,不会破坏语言的假设。如果你开始编写更高效的代码"对于R20上某些特定的底层内存方案,你今天可能会在这里或那里获得一些微小的性能提升,但是当R21出现时,很有可能你的所有代码都将被破坏而你'我会永远被R20困住。

考虑一下the R20.0 release announcement。跟上这种变化会消耗大部分的开发时间。

有些项目试图以完整的目的回溯运行时。例如,考虑Twisted。这些项目具体存在,以便所有(大的和非平凡的)努力不必在其下游的每个项目中重复。考虑到这一点,Erlang运行时,核心编译器,LFE项目,Elixir项目等自己是这种速度攻击的地方,绝对不是下游客户端代码。这里要注意的是快乐的事情(是的!我的严肃故事有一个美好的结局!)是这正是我们所看到的

关于"效率"

的说明

你追求什么样的效率?循环?巴士交通?缓存未命中? 财务成本? I / O-ops消除/绕过/写入?更一般的选择性缓冲处理?等

除非您为今年需要高效的已知硬件上的超紧密游戏引擎编写前端(因为明年硬件将会相形见绌)无论如何大多数速度攻击),花费更多的CPU时间很多比开发时间的数量要便宜,以确定在大规模并发运行时内发生的事情,数千个进程发送数百万的短暂消息,都在不同时间进行自己的垃圾收集。

有人可能想知道发生了什么的情况"我最常见的情况是人们试图使用Elixir作为"更快的Ruby"并没有写一个大规模并发系统,而是在EVM之上编写了一个大规模的单线程程序。写作的方法"快速" Erlang运行时的程序完全忽略了这一点。

你有一个非常特定的CPU密集型任务,绝对需要超快速度的情况,需要一个

  • 用Rust或C编写的端口
  • 以Rust或C
  • 编写的NIF
  • 可以通过网络与主节点通信的高性能计算节点,以某种语言编写,完全适合计算量大的任务(BERT非常有帮助)
  • 等待一两年的时间让运行时采用更多的性能增强和硬件来加快速度 - 对于并发系统来说,这种速度增加的速度是完全疯狂的,特别是如果你& #39;在你自己的硬件上运行(如果你正在运行"云"当然,这些改进使提供商受益但不是你,而且甚至那么让自己为更多的实例而不是试图欺骗运行时更便宜了。

编写单独的程序(或NIF)允许处理特定问题的任何开发人员或团队在单个统一的统一问题空间中工作,只关心履行主项目所交付的任何协议合同。这比使用Erlang或LFE或Elixir开发/团队在编写一些Erlang,然后是一些LangX,然后是一些Erlang,上下文切换,当然(或者更糟的是,上下文)之间的转换更有效率显着在他们是专家的一种语言和他们缺乏经验和天真的语言之间切换。

(另请注意,当您了解实际情况时,NIF应被视为最后的手段并且只考虑 。具体而言,您的处理工作量小,每次调用,可预测且NIF会破坏运行时的每一个安全保障。一个崩溃的NIF是一个崩溃的运行时 - 正是Erlang设计要避免的那种问题。在C中感到足够舒服以轻率推荐C NIF到处都是显然缺乏足够的C经验来编写那些NIF

在项目层面,效率问题主要是业务决策,而非技术决策。在社区FOSS的情况下,尝试超越运行时是一项糟糕的业务(或社区管理)。