【问题标题】:Are there any advantages using maps instead of records to hold state in Erlang processes?在 Erlang 进程中使用映射而不是记录来保存状态有什么好处吗?
【发布时间】:2015-10-23 15:13:30
【问题描述】:

我看到的大多数书籍或在线资源都使用记录来保存流程的状态(可能是因为这种方式已经超过(?)十年了)。另一方面,映射有效地用于替换标准库中的元组(例如childspecs in the supervisor module)。

例如,我正在阅读Learn You Some Erlang's Finite State Machines 章节,state 记录可以替换为在gen_fsm 所需的init/1 回调中声明的映射。

  • 不需要记录声明,到目前为止我读过的大部分内容,最佳做法是将它们保留在本地,因为.hrl 文件使跟踪错误变得更加困难。
  • 在函数子句中引用进程状态也会更短,但它们都清楚地传达了状态变量的结构,并且不需要考虑额外的几个字符。

另外,它会更有效吗?
我知道一个经过深思熟虑的基准可以回答我的问题,但我只需要几周的时间来学习 Erlang 并且 maps module 是相当新的并且仍然是 changing

更新:感谢我提供了非常糟糕的建议,我更彻底地阅读了LYSE chapter on maps,答案很明确:

使用记录的优点是在编译时就知道键 时间带来的优势

  • 快速访问特定值(比动态访问更快)
  • 额外的安全性(提前崩溃而不是破坏状态)
  • 更简单的类型检查

这些使记录绝对适合进程的内部状态,尽管偶尔会产生编写更冗长的负担 code_change 函数。

另一方面,Erlang 用户会使用记录来表示 复杂的嵌套键/值数据结构(奇怪地类似于 经常跨模块的面向对象语言) 边界,地图会有很大帮助。记录是错误的工具 工作。

【问题讨论】:

  • 为主管子规范使用映射还允许它们在未提供键时提供默认值,例如重新开始;这可以减少所需的样板数量

标签: erlang


【解决方案1】:

作为乔·阿姆斯特朗said

记录是万岁的地图!

我们谈论地图已经超过 12 年了,但现在它们是 留在这里。

为什么要等很久? - 我们希望地图成为记录的替代品 并且像记录一样高效,而且它并不明显 这样做。

所以,看起来地图没问题,我们已将项目从记录切换到地图,我们并没有感觉到任何性能损失。

一个限制: 如果我是对的,你不能像使用记录那样在 mnesia 中存储地图。

【讨论】:

  • 如果我可以问一下,您在项目中使用地图做什么?
  • 地图在我的代码中仍然是一个特定的用例。对于大多数情况,记录/元组的语义是合适的——因为数据具有特定的形状并且形状不是动态的。这是一种强类型参数。能够检查数据的形状是否正确可以帮助您尽早崩溃,而不是在一段时间内盲目地浏览一些地图形式的不良数据,也许在此过程中对某些外部资源进行破坏性更新,然后才意识到这是不是您认为的地图(哎呀!)。
  • 我们在 gen_server 进程中使用地图作为状态,在某些地方作为解码/编码 json 的源/结果
【解决方案2】:

我在 Learn You Some Erlang 网站上添加了一章专门介绍地图:http://learnyousomeerlang.com/maps

墨西哥对峙部分专门将地图与记录和字典进行比较。从语义上讲,映射比记录更类似于字典,我的建议是使用记录有意义的记录(具有 O(1) 访问权限的已知类型的受限键集),以及使用过字典的映射(异构、灵活的键/值对集)。

【讨论】:

  • 谢谢,我之前只是略读了这一章,但答案很明显。我还没有阅读 Richard O'Keefe 的框架提案,但所有消息来源都说它非常棒,即使它不会被包含(还没有?)在 Erlang/OTP 中。
猜你喜欢
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 2020-12-22
  • 2019-06-04
  • 1970-01-01
  • 2016-11-05
  • 2012-11-29
  • 2011-04-29
相关资源
最近更新 更多