3

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|...]]]}

現在、テーブルから1986392 long を取得するのに 106000マイクロ秒listかかりますが、これはかなり高速ですよね? リストは要素ごとに 2 語です。したがって、データは 4x1.7MB です。

EDIT 2 : erlang-question ( http://groups.google.com/group/erlang-programming/browse_thread/thread/5581a8b5b27d4fe1 ) でスレッドを開始しましたが、0.1 秒がかなりの時間であることがわかりました。 memcpy() (データをプロセスのヒープに移動します)。一方、Odobenus Rosmarus の回答では、バイナリの取得に時間がかからない理由が説明されています。

4

1 に答える 1

5

バイナリ自体 (64 ビットを超えるもの) は、プロセス ヒープの外の特別なヒープに格納されます。

そのため、ets テーブルからのバイナリの取得は、バイナリの「Procbin」部分だけをプロセス ヒープに移動します。(大まかに言えば、バイナリメモリとサイズのバイナリの開始へのポインタです)。

于 2012-01-11T01:19:17.120 に答える