erlang中application来获取变量与ets获取变量的速度比较

今天有些数据要缓存起来获取,分别比较了application和ets获取变量的方法。html

结论:缓存

appcation:get_env/2 方法和 ets:lookup/2 方法都是只须要一次ets读,最快。若是在程序运行过程当中插入数据能够选择ets:lookup/2,像如今rebar3能够在程序启动后把数据存储在appcation变量里面,能够选择appcation:get_env/2。另外ets:lookup/2要本身写比较逻辑,appcation:get_env/2已经封装好逻辑了,使用相对简单。app

application:get_env/1方法须要2次读ets,相对较慢。
mnesia:dirty_read/1方法须要3次读ets,最慢,但能够在多个节点中使用。

参考:[erlang-questions] "speed question"spa

Generally, the performance should be insignificant, but…

ets:lookup/2: 
  1 ets read (duh), but obviously, you need to write more code

application:get_env/2:
  1 ets read

application:get_env/1:
   2 ets reads (one to find the current application)

mnesia:dirty_read/1: 
  - 1 get()
  - 3 ets reads, if data is local (where_to_read, storage_type, lookup)

Beyond the performance differences, there are semantic issues. 
Application environment variables are really meant to be static, 
either hard-coded in the .app file, or overridden at startup. 
They can also be changed at upgrades, but the expectation isn't that they change dynamically.

In fact, for data that is truly static, 
the fastest access is if the data is simply hard-coded in an erlang module. 
Given that modules are easy to reload, these values can still be changed with low frequency.

So for system preferences, it is generally better to store the values in a database.

代码实现:code

%% appcation.erl
get_env(Key) -> 
    application_controller:get_pid_env(group_leader(), Key).

get_env(Application, Key) -> 
    application_controller:get_env(Application, Key).


%% application_controller.erl
get_pid_env(Master, Key) ->
    case ets:match(ac_tab, {{application_master, '$1'}, Master}) of
	[[AppName]] -> get_env(AppName, Key);
	_ -> undefined
    end.

get_env(AppName, Key) ->
    case ets:lookup(ac_tab, {env, AppName, Key}) of
	[{_, Val}] -> {ok, Val};
	_ -> undefined
    end.

能够看到application:get_env/1要使用ets:match/2方法,理论上要慢不少。orm

代码实现都是从名为ac_tab的ets表里面读取变量内容。xml

mnesia就不贴代码了,我如今还不够深刻理解,之后有机会再理解。htm

相关文章
相关标签/搜索