Current section

Files

Jump to
erlcass benchmarks benchmark.erl
Raw

benchmarks/benchmark.erl

-module(benchmark).
-include("erlcass.hrl").
-include_lib("cqerl/include/cqerl.hrl").
-include_lib("marina/include/marina.hrl").
-include_lib("shackle/include/shackle.hrl").
-define(QUERY, <<"SELECT col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11, col12, col13, col14 FROM test_table WHERE col1 = ?">>).
-define(ARG_VAL, <<"hello">>).
-define(DRIVER_ERLCASS, erlcass).
-define(DRIVER_CQERL, cqerl).
-define(DRIVER_MARINA, marina).
-export([
run/3,
start/1
]).
start(Module) ->
case application:ensure_all_started(Module) of
{ok, [_H|_T]} ->
case Module of
?DRIVER_ERLCASS ->
ok = erlcass:add_prepare_statement(testing_query, {?QUERY, ?CASS_CONSISTENCY_ONE});
_ ->
ok
end;
_ ->
ok
end.
get_client(?DRIVER_ERLCASS) ->
undefined;
get_client(?DRIVER_CQERL) ->
{ok, Client} = cqerl:get_client(),
Client;
get_client(?DRIVER_MARINA) ->
undefined;
get_client(_) ->
throw(invalid_module).
close_client(?DRIVER_ERLCASS, _Client) ->
ok;
close_client(?DRIVER_CQERL, Client) ->
cqerl:close_client(Client);
close_client(?DRIVER_MARINA, _) ->
ok;
close_client(_, _) ->
throw(invalid_module).
execute_async(?DRIVER_ERLCASS, _Client) ->
{ok, _Tag} = erlcass:async_execute(testing_query, [?ARG_VAL]),
ok;
execute_async(?DRIVER_CQERL, Client) ->
true = is_reference(cqerl:send_query(Client, #cql_query{
statement=?QUERY,
values=[{col1, ?ARG_VAL}],
consistency = one
})),
ok;
execute_async(?DRIVER_MARINA, _Client) ->
{ok, _} = marina:async_reusable_query(?QUERY, [?ARG_VAL], ?CONSISTENCY_ONE, [], self(), 5000),
ok;
execute_async(_Module, _Client) ->
throw(invalid_module).
receive_response(?DRIVER_ERLCASS) ->
receive
{execute_statement_result, _Tag, Rs} ->
case Rs of
{ok, _Cols, _Rows} ->
ok;
UnexpectedResult ->
UnexpectedResult
end
end;
receive_response(?DRIVER_CQERL) ->
receive
{result, _Tag, Rs} ->
case is_record(Rs, cql_result) of
true ->
ok;
_ ->
Rs
end;
{error, _Tag, Reason} ->
Reason
end;
receive_response(?DRIVER_MARINA) ->
receive
{#cast{}, Response} ->
case marina:response(Response) of
{ok, _} ->
ok;
UnexpectedResponse ->
UnexpectedResponse
end;
Msg->
io:format("received: ~p~n", [Msg]),
ok
end;
receive_response(_Module) ->
throw(invalid_module).
%benchmark internals
consumer_loop(_Module, TotalResults, SuccessResults, FailedResults, 0) ->
%% io:format("**** Test Completed => module: ~p results: ~p success: ~p failed: ~p **** ~n",[Module,
%% TotalResults,
%% SuccessResults,
%% FailedResults
%% ]),
{TotalResults, SuccessResults, FailedResults};
consumer_loop(Module, TotalResults, SuccessResults, FailedResults, LimitReq) ->
case receive_response(Module) of
ok ->
consumer_loop(Module, TotalResults +1 , SuccessResults +1, FailedResults, LimitReq -1);
UnexpectedResponse ->
io:format("## Unexpected result: ~p ~n", [UnexpectedResponse]),
consumer_loop(Module, TotalResults +1 , SuccessResults, FailedResults + 1, LimitReq -1)
end.
producer_loop(_Module, _Client, 0) ->
ok;
producer_loop(Module, Client, NumRequests) ->
ok = execute_async(Module, Client),
producer_loop(Module, Client, NumRequests -1).
run(Module, NrProcesses, NrReq) ->
start(Module),
io:format("Test will start in 1 sec ...~n"),
timer:sleep(1000),
io:format("Test started ...~n"),
ReqPerProcess = round(NrReq/NrProcesses),
Self = self(),
Fun = fun() ->
Client = get_client(Module),
producer_loop(Module, Client, ReqPerProcess),
consumer_loop(Module, 0, 0, 0, ReqPerProcess),
close_client(Module, Client),
Self ! {self(), done}
end,
List = lists:seq(1, NrProcesses),
{Time, _} = timer:tc(fun()-> bench(Fun, List) end),
io:format("Time to complete: ~p ms ~n", [Time/1000]).
bench(Fun, ProcsList) ->
Pids = [spawn_link(Fun) || _ <- ProcsList],
[receive {Pid, done} -> ok end || Pid <- Pids],
ok.