-module(eptest). -compile(export_all). %% run(Iterations) -> { Eets, Ets, Edb, Empty } %% Eets, Ets, Edb ::= AccessPair %% Empty ::= Time %% AccessPair ::= {Insert, Lookup} %% Insert, Lookup ::= Time %% Time, Iterations ::= integer() %% %% Time is total time in microseconds for the given iterations %% %% eets: A linear hash table kept on the process heap; uses tuples %% ets: Normal ets table %% edb: Emulated ets using eets and gen_server %% (one name server; one server for the table itself) %% %% Each test is run in a separate process. %% Test loop overhead is estimated by Empty; subtract from other numbers. %% %% Payload is given by data(). Ets and Edb times will vary with payload. %% run(N) -> Time2 = do_run(run_p, [N]), Time3 = do_run(run_ets, [N]), Time4 = do_run(run_other, [empty, [N]]), [{proc, Time2}, {ets, Time3}, {empty, Time4}]. data() -> %% lists:seq(1,5). lists:seq(1,1000). empty(N) when N>0 -> empty(N-1); empty(N) -> done. p(N,T) when N>0 -> T ! {self(), get}, receive {T, Result} -> Result end, p(N-1,T); p(N, T) -> T. ets(N,Data,T) when N>0 -> ets:insert(T, {N, Data}), ets(N-1,Data,T); ets(N, Data, T) -> T. ets2(N,T) when N>0 -> [Obj] = ets:lookup(T, N), ets2(N-1,T); ets2(N, _) -> done. do_run(F, Args) -> Pid = spawn_link(?MODULE, F, [self()|Args]), receive {Pid, Time} -> Time end. run_p(Parent, N) -> Data = data(), T = spawn_link(fun() -> process_flag(priority, high), server_loop(Data) end), {Time1, T1} = timer:tc(?MODULE, p, [N, T]), {Time2, T2} = timer:tc(?MODULE, p, [N, T1]), Time3 = check_res(timer:tc(?MODULE, p, [N, T2]), run_p), Parent ! {self(), {Time1, Time2, Time3}}. run_ets(Parent, N) -> T = ets:new(test, [set, named_table]), T1 = test, Data = data(), {Time, T2} = timer:tc(?MODULE, ets, [N, Data, T1]), {Time1, T3} = timer:tc(?MODULE, ets, [N, Data, T2]), Time2 = check_res(timer:tc(?MODULE, ets2, [N, T3]), run_ets), Parent ! {self(), {Time, Time1, Time2}}. run_other(Parent, F, Args) -> Time = check_res(timer:tc(?MODULE, F, Args), {run_other, F}), Parent ! {self(), Time}. check_res({Time, {'EXIT', Reason}}, Context) -> exit({Reason, Context}); check_res({Time, _}, _) -> Time. server_loop(Data) -> receive {Pid, get} -> Pid ! {self(), Data}, server_loop(Data) end.