2012-01-10 14 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のバイナリはテーブルから取得する時間がかかります!

EDIT:私は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|...]]]} 

は、今ではかなり速いですテーブルから1986392長いlistを取得するために、106000のマイクロをとり、そうではありませんか?リストは1要素につき2ワードです。したがって、データは4x1.7MBです。

EDIT 2:私はアーラン-質問(http://groups.google.com/group/erlang-programming/browse_thread/thread/5581a8b5b27d4fe1)上のスレッドを開始し、それが0.1秒はかなりそれは(のmemcpyを行うために要する時間であることが判明)(プロセスのヒープにデータを移動します)。一方、Odobenus Rosmarusの答えは、バイナリの取得に0時間かかる理由を説明しています。

答えて

5

バイナリ自体(64ビットより長いもの)は、プロセスヒープの外側の特別なヒープに格納されます。

したがって、etsテーブルからバイナリを取得すると、バイナリの「Procbin」部分だけをプロセスヒープに移動します。 (おおよそ、バイナリのメモリとサイズでバイナリを開始するポインタです)。

+0

お返事ありがとうございます。私は 'lists'を試して、1986392の検索には106000マイクロ秒を要しました。かなり速いです。 –

+0

良い答えです!あなたは64バイトを意味し、ビットは意味しません:) –

関連する問題