之前對於erlang的進程字典了解的不夠清楚,只是知道put()、get()函數,即存值和取值,而每個put、get中都有自己的一對Key——Value(鍵值對)與之對應。一個Key對應一個Value.在erlang中,啟動進程節點之后,進程字典的put、get的值是對緩存的處理,而對數據庫的操作,相當於是對硬盤的一個操作,可以理解成是一個數據的備份。
舉個簡單的例子:在游戲中都有好友操作,啟動服務之后,玩家點擊添加好友操作,進程的節點已經開啟,先從內存中獲取玩家的進程字典的Value的值,這里的值是一個record記錄,然后再是對數據庫的操作,X_db:get_Fname_from_mnesia( ),即從數據庫(這里是mnesia)中從硬盤上get到另一個玩家的信息.這樣的訪問速度會更快,因為從內存讀取數據的速率遠遠大於硬盤讀取。當玩家下線關閉自己的客戶端之后,與之對應的進程節點將銷毀,其進程字典同樣隨之銷毀,但數據庫備份的數據在硬盤上是不會銷毀變化的。玩家讀取數據,改變數據信息,都是先通過進程字典,隨后放入數據庫中與之改變的。在其他語言中,大都叫哈希hash,即散列表或散列映射。
看了霸爺寫的進程字典的訪問速度的帖子,有些感悟,如下:
-module(dicttest).
-export([test_put/1, test_get/1]).
test_put(N)->
Start = erlang:now(),
dotimes(N, fun (I) -> put(I, hello) end),
Stop = erlang:now(),
N / time_diff(Start, Stop).
test_get(N)->
Start = erlang:now(),
dotimes(N, fun (I) -> get(I) end),
Stop = erlang:now(),
N / time_diff(Start, Stop).
dotimes(0, _) -> done;
dotimes(N, F) ->
F(N),
dotimes(N - 1, F).
time_diff({A1,A2,A3}, {B1,B2,B3}) ->
(B1 - A1) * 1000000 + (B2 - A2) + (B3 - A3) / 1000000.0 .
root@nd-desktop:~# erl -smp disable +h 9999999
Erlang R13B01 (erts-5.7.2) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.2 (abort with ^G)
1> dicttest:test_put(1000000).
9174480.26569295
2> dicttest:test_get(1000000).
34172105.390379503
3> length(element(2, process_info(self(), dictionary))).
1000000
測試的速度相當的快了。 百萬條級別,插入100ns, 查詢40ns. 而ets的速度大概是us,差了一個數量級別。
詳見:霸爺的文章http://mryufeng.iteye.com/blog/435642
發現進程字典的訪問速度遠大於ets的速率,而“mochiweb把解析的數據放到process dictionary,稱其為cache”。這之前,一直理解成了進程字典中的鍵值對的處理是對內存的操作,上述例子明顯告訴我們:它其實是對緩存的處理。
mochiweb這個開源的框架確實很神奇,有待繼續研究。