pooler_perf_test.erl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. -module(pooler_perf_test).
  2. -compile([export_all]).
  3. -include_lib("eunit/include/eunit.hrl").
  4. -define(gv(X, L), proplists:get_value(X, L)).
  5. setup(InitCount, MaxCount, NumPools) ->
  6. MakePool = fun(I) ->
  7. N = integer_to_list(I),
  8. Name = "p" ++ N,
  9. Arg0 = "pool-" ++ Name,
  10. [{name, Name},
  11. {max_count, MaxCount},
  12. {init_count, InitCount},
  13. {start_mfa,
  14. {pooled_gs, start_link, [{Arg0}]}}]
  15. end,
  16. Pools = [ MakePool(I) || I <- lists:seq(1, NumPools) ],
  17. application:set_env(pooler, pools, Pools),
  18. application:start(pooler).
  19. consumer_cycle(N) ->
  20. consumer_cycle(N, 0, 0).
  21. consumer_cycle(N, NumOk, NumFail) when N > 0 ->
  22. P = pooler:take_member(),
  23. case P of
  24. Pid when is_pid(Pid) ->
  25. true = is_process_alive(P),
  26. pooler:return_member(P, ok),
  27. consumer_cycle(N - 1, NumOk + 1, NumFail);
  28. _ ->
  29. consumer_cycle(N - 1, NumOk, NumFail + 1)
  30. end;
  31. consumer_cycle(0, NumOk, NumFail) ->
  32. [{ok, NumOk}, {fail, NumFail}].
  33. test1() ->
  34. N = 10000,
  35. {Time, _} = timer:tc(fun() ->
  36. consumer_cycle(N)
  37. end, []),
  38. Time / N.
  39. consumer_worker(N, Parent) ->
  40. spawn(fun() ->
  41. Parent ! {self(), consumer_cycle(N)}
  42. end).
  43. test3(W, N) ->
  44. [consumer_worker(W, self()) || _I <- lists:seq(1, N)].
  45. test2(Iter, Workers) ->
  46. Self = self(),
  47. {Time, Res} =
  48. timer:tc(fun() ->
  49. Pids = [ consumer_worker(Iter, Self)
  50. || _I <- lists:seq(1, Workers) ],
  51. gather_pids(Pids)
  52. end, []),
  53. {NumOk, NumFail} = lists:foldr(fun({_, L}, {O, F}) ->
  54. {O + ?gv(ok, L),
  55. F + ?gv(fail, L)}
  56. end, {0, 0}, Res),
  57. {Time, [{ok, NumOk}, {fail, NumFail}]}.
  58. gather_pids(Pids) ->
  59. gather_pids(Pids, []).
  60. gather_pids([Pid|Rest], Acc) ->
  61. receive
  62. {Pid, Ans} ->
  63. gather_pids(Rest, [{Pid, Ans}|Acc]);
  64. stop -> stop
  65. end;
  66. gather_pids([], Acc) ->
  67. Acc.
  68. pooler_take_return_test_() ->
  69. {foreach,
  70. % setup
  71. fun() ->
  72. InitCount = 10,
  73. MaxCount = 100,
  74. NumPools = 5,
  75. setup(InitCount, MaxCount, NumPools)
  76. end,
  77. fun(_X) ->
  78. application:stop(pooler)
  79. end,
  80. [
  81. {"take return cycle single worker",
  82. fun() ->
  83. NumCycles = 10000,
  84. Ans = consumer_cycle(NumCycles),
  85. ?assertEqual(NumCycles, ?gv(ok, Ans)),
  86. ?assertEqual(0, ?gv(fail, Ans))
  87. end},
  88. {"take return cycle multiple workers",
  89. fun() ->
  90. Self = self(),
  91. Iter = 100,
  92. Workers = 100,
  93. Pids = [ consumer_worker(Iter, Self)
  94. || _I <- lists:seq(1, Workers) ],
  95. Res = gather_pids(Pids),
  96. {NumOk, NumFail} =
  97. lists:foldr(fun({_, L}, {O, F}) ->
  98. {O + ?gv(ok, L), F + ?gv(fail, L)}
  99. end, {0, 0}, Res),
  100. ?assertEqual(0, NumFail),
  101. ?assertEqual(100*100, NumOk)
  102. end}
  103. ]
  104. }.