我知道在Erlang中(至少)有三种方法可以使状态可变:
- ETS表格
- 第一个月
- 进程字典
它们的基本用法在我看来非常相似:
% ETS
1> ets:new(table1, [named_table]).
2> ets:insert(table1, {thing}).
3> ets:lookup(table1, thing).
[{thing}]
% persistent_term
1> persistent_term:put(table2, thing).
2> persistent_term:get(table2).
thing
% Process dictionary
1> put(table3, thing).
2> get(table3).
thing
使用一种方法与使用另一种方法的区别和优缺点是什么?
我发现ETS的行为更像一个Map,但是它与将Map保存在persistent_term
或进程字典中有什么不同呢?
2条答案
按热度按时间2ul0zpep1#
persistent_term
和ets
公开了一个类似的API,但它们是不同的,我引用manual:持久术语是一项高级功能,不能普遍替代ETS表。
不同之处在于术语存储在哪里以及更新时会发生什么,ETS术语在读取时会被复制到进程堆中,而
persistent_term
术语只被引用。这导致当persistent_term
中的一个项被更新时,所有拥有该术语副本(引用)的进程都需要将其复制到它们的堆中才能继续使用它。对于庞大的术语,引用它们而不是复制它们可以节省大量时间,但是更新的代价是严厉的。
同样,
persistent_term
只是一个Map,而ETS可以是集合、有序集合、包或复制包,ETS还提供选择和匹配语义。persistent_term
被用作ETS所用于的非常特定的使用情形的优化替代品。关于进程字典,它是进程内部的一个本地
#{}
,总是可用的。ETS和persistent_term
对每个进程都可用,本地进程字典对每个进程都不同。使用进程字典时要非常小心,因为它会损害可读性。jchrr9hc2#
@José回答的一些免费信息:
process_dictionary是本地的,它与进程一起终止,无法从外部进程访问
persistent_element是全局的,它只会随节点而死。它可以被任何进程访问,而不受控制。
ETS由一个进程拥有,它可以被不同的进程共享,它与所有者一起消亡,所有权可以交给另一个进程,它提供一些访问控制(公共、私有、受保护)以及不同的组织类型和访问。
shell中的一个简短会话显示了(大部分)这些差异。