我有一些模块级状态,我想写一次,然后再也不修改。
具体来说,我有一组字符串,我想稍后用来查找内容。这样做的有效和普通方法是什么?
我可以创建一个始终返回相同集合的函数:
my_set() -> sets:from_list(["a", "b", "c"]).
Run Code Online (Sandbox Code Playgroud)
VM 会对此进行优化,还是每次都会重新运行构建集合的代码?我怀疑该集合只会获得 GCd。
在这种情况下,我是否应该将集合缓存在进程字典中,以模块 md5 之类的独特内容为键?
Key = proplists:get_value(md5, module_info()), put(Key, my_set())
另一种解决方案是让调用者调用一个init函数来取回一个不透明的状态块,然后将该状态传递给模块中的每个函数。
编译时常量,如您的示例 list ["a", "b", "c"],将在加载模块时存储在旁边的常量池中,并且不会在每次运行表达式时重新构建。(在过去,每个新调用都会根据其元素重建列表。)无论多么复杂,这都适用于所有常量(如元组列表的列表)。但是当你调用一个像 set:from_list/1 这样的函数时,编译器不能假设 set 模块使用的任何表示,并且 set 将从该常量列表动态构造。
虽然 ETS 表可以工作,但对于较大的常量(例如,包含许多条目的集合或映射)效率较低,因为 ETS 表具有与进程相同的内存模型 - 数据通过复制写入和读取,如如果通过发送消息。如果常量很小,复制它们和在本地重新创建它们之间的区别可以忽略不计,如果常量很大,你就浪费时间复制它们。
你想要的是一个名为 Persistent Term Storage 的相当新的功能:https : //erlang.org/doc/man/persistent_term.html(自 Erlang/OTP 21 起)。它类似于处理编译时常量的方式,因此在查找值时没有复制。(关键可能是您的模块的名称。) Persistent Term 的目的几乎是一次写入多次读取的存储 - 您可以更新存储的条目,但这是一个更昂贵的操作,可能会触发全局 GC。
| 归档时间: |
|
| 查看次数: |
51 次 |
| 最近记录: |