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

相關文章
相關標籤/搜索