pooler_perf_test.erl 3.5 KB

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