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

zet*_*avg 6 erlang elixir

我们了解Elixir的一个事实是,存储在内存中的数据结构是不可变的,变量只是指向这些数据结构的指针.

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


对我来说,这样做的目的是我们可以了解Elixir/Erlang在处理重复值时如何管理内存,例如两个相同的字符列表,或者特别是在某些情况下元组和列表可以共享其内容,并且写得更有效码.

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

zxq*_*xq9 12

TL; DR:

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

讨论

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

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

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

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

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

只需考虑R20.0发布公告.跟上这种变化会消耗大部分的开发时间.

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

关于"效率"的说明

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

除非你为今年需要高效的已知硬件上的超紧密游戏引擎编写前端(因为明年硬件将使大多数速度硬件相形见绌),支付更多的CPU时间远远低于开发人员需要花时间来确定大规模并发运行时内发生的事情,数千个进程发送数百万条短暂的消息,所有进程都在不同时间进行自己的垃圾收集.

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

如果您有一个非常特定的CPU密集型任务,绝对需要超快的速度调用其中一个

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

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

(还要记住,NIF应该被视为最后的手段,只有当你知道你的实际情况时才会考虑.具体来说,你的处理工作是小的每次通话,可预测和有限的,并且频繁的呼叫开销是你的NIF超过了NIF中的处理速度.NIF破坏了运行时的每一个安全保障.崩溃的NIF是一个崩溃的运行时 - 正是Erlang设计要避免的那种问题.任何在C语言中感到舒服的人都会轻率推荐C语言各地的NIF 显然缺乏足够的C经验来编写那些NIF.)

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

  • 这是非常出色,非常好的答案. (4认同)