之前对于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这个开源的框架确实很神奇,有待继续研究。