2009-09-27 92 views

回答

12

由於ETS存儲在erlang進程以外的堆中,因此不會進行垃圾回收。這意味着,當你把東西放入ets中時,它會被複制到它中,當你把它拿出來時,你會在你的過程中得到一份副本。大量的ets查詢可能會導致您的流程過度考慮(但這隻與非常高的吞吐量有關)。

進程字典是垃圾回收。它存儲在進程自己的堆中。所以當你查看它時,你會得到一個與你輸入的完全相同的值的參考。存儲在流程字典中的值不會被壓縮。

這兩種方法都是非純的,即它們有副作用。是的,這是不好的,是的,這不是我們有兩種選擇的原因。

+1

幾乎所有的Erlang書上說,我們應該從工藝庫遠離,但我認爲使用ETS是沒有太大的不同。 – 2009-09-27 14:11:43

+14

「幾乎所有的Erlang書籍」......這是否意味着三分之二? =) – Zed 2009-09-27 15:01:58

9

好處是:

  • 其他進程可以訪問ETS表直接
  • ETS給你搜索/匹配/重複設施,而進程字典只是一個key-value存儲。
  • 您可以在一個步驟中將表格保存/加載到文件中
  • 如果您的所有者進程死亡,則表可以由其他人繼承,這樣數據就不會丟失。
9

ETS或多或少表現得好像表格在單獨的進程中一樣,並且請求是發送到該進程的消息。雖然它沒有與ETS的屬性建模的過程一起實現。實際上可以通過流程來實施ETS。

這意味着副作用屬性與其餘的Erlang一致。

進程字典就像Erlang中的其他東西一樣,並且添加它是一個很大的錯誤。沒有理由使用進程字典而不是像dict或gb_trees這樣的進程本地字典之一。

+2

我猜ETS和「基於過程的ETS」之間的區別在於前者可以在使用精細鎖時真正併發地訪問,而後者將始終強制同步(又名序列化)。 – Zed 2009-09-27 20:14:00

+1

由於訪問ETS的過程並非同步,所以「調用」過程必須等待,直到它從ETS獲得「回覆」。不同之處在於,流程字典將始終在該流程的上下文中,而ETS將是對共享數據的同步訪問。 – rvirding 2009-10-01 13:20:37

+1

我知道rvirding已經評論過,他是Erlang的大師之一,但在這一點上,我虛心不同。 我確實看到需要(並已經使用)流程字典的內部管理功能。 有時我們需要在一個進程內存儲一個不屬於進程主函數一部分的函數的狀態,例如記錄器可以維護狀態,並且將記錄器狀態放入主應用程序邏輯是不好的。 – 2016-06-23 18:39:06

2

毫無疑問,ETS具有更多的功能並且更加複雜。但是......

  • 隨着進程字典更新/查找操作只移動引用,而不是整個數據(見基督徒準確的答案),它可以更快,尤其是對大數據結構。一旦我重構了一部分代碼以保持proc中的大型和頻繁訪問的數據結構。而不是ETS,我們在這部分代碼中的速度提高了30%。

  • 在很多情況下,數據只能由一個進程訪問。在這種情況下,我認爲proc.dict和ETS之間沒有太大的理論差異。兩者都用於保持記憶中的副作用。 此外,您可以訪問另一個進程的proc.dict,如

    process_info(whereis(net_kernel),dictionary)。

相關問題