2012-01-10 72 views
3

我知道ETS表的查找時間是不變的。但是我也聽說過,表格被保存在進程之外,當檢索數據時,它需要移動到進程堆中。所以,這很昂貴。但是,如何解釋這一點:從ETS表中檢索數據

18> {Time, [[{ok, Binary}]]} = timer:tc(ets, match, [utilo, {a, '$1'}]). 
{0, 
[[{ok,<<255,216,255,225,63,254,69,120,105,102,0,0,73, 
     73,42,0,8,0,0,0,10,0,14,...>>}]]} 
19> size(Binary). 
1759017 

1.7 MB二進制需要0時間從表中檢索!?

編輯:當我看到Odobenus Rosmarus的回答後,我決定將二進制轉換爲列表。下面是結果:

1> {ok, B} = file:read_file("IMG_2171.JPG"). 
{ok,<<255,216,255,225,63,254,69,120,105,102,0,0,73,73,42, 
     0,8,0,0,0,10,0,14,1,2,0,32,...>>} 
2> size(B). 
1986392 
3> L = binary_to_list(B). 
[255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,0,8,0,0, 
0,10,0,14,1,2,0,32,0,0|...] 
4> length(L). 
1986392 
5> ets:insert(utilo, {a, L}). 
true 
6> timer:tc(ets, match, [utilo, {a, '$1'}]). 
{106000, 
[[[255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,0,8,0, 
    0,0,10,0,14,1,2|...]]]} 

現在只需要106000 微秒來檢索的速度非常快表1986392長list,不是嗎?列表是每個元素2個字。因此數據是4x1.7MB。

編輯2:我開始在二郎個問題(http://groups.google.com/group/erlang-programming/browse_thread/thread/5581a8b5b27d4fe1)線程和事實證明,0.1秒非常需要做的memcpy()(移動數據到進程的堆)的時間。另一方面,Odobenus Rosmarus的回答解釋了爲什麼檢索二進制文件需要0次。

回答

5

二進制文件本身(超過64位)存儲在特殊堆中,在進程堆外部。

因此,從ets表中檢索二進制文件只是將'Procbin'部分的二進制文件處理堆。 (大概是指向二進制文件的內存和大小開始的指針)。

+0

感謝您的回答。我試着用'list'和1986392長列表檢索106000微秒。蠻快。 – 2012-01-11 06:38:55

+0

很好的答案!你的意思是64字節,而不是位:) – 2012-01-22 12:17:42