我们了解Elixir的一个事实是,存储在内存中的数据结构是不可变的,变量只是指向这些数据结构的指针.
有没有办法让我们得到一个变量的内存地址指向,而不是该内存位置的内容(即变量的取消引用值)?
对我来说,这样做的目的是我们可以了解Elixir/Erlang在处理重复值时如何管理内存,例如两个相同的字符列表,或者特别是在某些情况下元组和列表可以共享其内容,并且写得更有效码.
例如,当您更新元组时,除了已替换的条目之外,所有条目都在旧元组和新元组之间共享.换句话说,Elixir中的元组和列表能够共享其内容.
zxq*_*xq9 12
不,你无法获得变量的内存位置.
原则上一切都是复制的.每个进程都有自己的堆.这就是事情的方式.
实际上有一些潜在的速度黑客.最值得注意的是
binary:copy/1,2).如果您要为EVM编写代码,无论使用何种语言,您都应该放弃这样的想法,即您将超越运行时.这与完全相同的原因是,试图超越大多数C(尤其是C++)编译器优化几乎无处不在是一种禁止的做法.
每个主要版本都包含一些新实现的性能增强,不会破坏语言的假设.如果您开始编写对R20上某些特定底层内存方案"更有效"的代码,那么今天在这里或那里可能会获得一些微小的性能提升,但是当R21出现时,很可能会破坏所有代码并且你永远只会被R20困住.
只需考虑R20.0发布公告.跟上这种变化会消耗大部分的开发时间.
有些项目试图以完整的目的回溯运行时.例如,考虑扭曲.这些项目具体存在,以便所有(大的和非平凡的)努力不必在其下游的每个项目中重复.考虑到这一点,Erlang运行时,核心编译器,LFE项目,Elixir项目等本身就是这种速度攻击的地方,绝对不是下游客户端代码.这里要注意的是快乐的事情(是的!我的严肃故事有一个美好的结局!)就是这正是我们所看到的.
你追求什么样的效率?循环?巴士交通?缓存未命中?财务费用?I/O-ops消除/绕过/写入?更一般的选择性缓冲处理?等等
除非你为今年需要高效的已知硬件上的超紧密游戏引擎编写前端(因为明年硬件将使大多数速度硬件相形见绌),支付更多的CPU时间远远低于开发人员需要花时间来确定大规模并发运行时内发生的事情,数千个进程发送数百万条短暂的消息,所有进程都在不同时间进行自己的垃圾收集.
有人可能想要"知道发生了什么"的情况,我最常见的情况是人们试图将Elixir用作"更快的Ruby"而且编写的不是大规模并发系统,而是一个大规模的单线程在EVM之上的程序.在Erlang运行时编写"快速"程序的方法完全忽略了这一点.
如果您有一个非常特定的CPU密集型任务,绝对需要超快的速度调用其中一个
编写单独的程序(或NIF)允许处理特定问题的任何开发人员或团队在单个统一的统一问题空间中工作,只关心履行主项目所交付的任何协议合同.这是明显比有一个Erlang或写一些Erlang的,然后一些LangX之间LFE或药剂开发/团队翻转更有效率,那么一些二郎神再次,上下文切换的过程(或者更糟的事,一种语言之间的上下文切换中,他们是专家,是一个缺乏经验和天真的人.
(还要记住,NIF应该被视为最后的手段,只有当你知道你的实际情况时才会考虑.具体来说,你的处理工作是小的每次通话,可预测和有限的,并且频繁的呼叫开销是你的NIF超过了NIF中的处理速度.NIF破坏了运行时的每一个安全保障.崩溃的NIF是一个崩溃的运行时 - 正是Erlang设计要避免的那种问题.任何在C语言中感到舒服的人都会轻率推荐C语言各地的NIF 显然缺乏足够的C经验来编写那些NIF.)
在项目层面,效率问题主要是业务决策,而不是技术决策.这是一个糟糕的业务(或社区管理,在社区FOSS的情况下)决定尝试超越运行时.