首页 > 代码库 > 关于erlang中的进程字典(process dictionary)的新理解及其访问速度 (copy来的)

关于erlang中的进程字典(process dictionary)的新理解及其访问速度 (copy来的)

 之前对于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,差了一个数量级别。

       发现进程字典的访问速度远大于ets的速率,而“mochiweb把解析的数据放到process dictionary,称其为cache”。这之前,一直理解成了进程字典中的键值对的处理是对内存的操作,上述例子明显告诉我们:它其实是对缓存的处理。