您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

216 行
7.9 KiB

  1. -module(acTc).
  2. -compile(inline).
  3. -compile({inline_size, 128}).
  4. -export([
  5. tc/1
  6. , tc/2
  7. , tc/3
  8. , ts/4
  9. , tm/5
  10. , cvrTimeUnit/3
  11. , test/1
  12. ]).
  13. %% Measure the execution time (in nanoseconds) for Fun().
  14. -spec tc(Fun :: function()) -> {Time :: integer(), Value :: term()}.
  15. tc(F) ->
  16. T1 = erlang:monotonic_time(),
  17. Val = F(),
  18. T2 = erlang:monotonic_time(),
  19. Time = cvrTimeUnit(T2 - T1, native, nanosecond),
  20. {Time, Val}.
  21. %% Measure the execution time (in nanoseconds) for Fun(Args).
  22. -spec tc(Fun :: function(), Arguments :: [term()]) -> {Time :: integer(), Value :: term()}.
  23. tc(F, A) ->
  24. T1 = erlang:monotonic_time(),
  25. Val = apply(F, A),
  26. T2 = erlang:monotonic_time(),
  27. Time = cvrTimeUnit(T2 - T1, native, nanosecond),
  28. {Time, Val}.
  29. %% Measure the execution time (in nanoseconds) for an MFA.
  30. -spec tc(Module :: module(), Function :: atom(), Arguments :: [term()]) -> {Time :: integer(), Value :: term()}.
  31. tc(M, F, A) ->
  32. T1 = erlang:monotonic_time(),
  33. Val = apply(M, F, A),
  34. T2 = erlang:monotonic_time(),
  35. Time = cvrTimeUnit(T2 - T1, native, nanosecond),
  36. {Time, Val}.
  37. -spec cvrTimeUnit(Time :: integer(), FromUnit :: erlang:time_unit(), ToUnit :: erlang:time_unit()) -> ConvertedTime :: integer().
  38. cvrTimeUnit(Time, FromUnit, ToUnit) ->
  39. try
  40. FU =
  41. case FromUnit of
  42. native -> erts_internal:time_unit();
  43. perf_counter -> erts_internal:perf_counter_unit();
  44. nanosecond -> 1000 * 1000 * 1000;
  45. microsecond -> 1000 * 1000;
  46. millisecond -> 1000;
  47. second -> 1
  48. end,
  49. TU =
  50. case ToUnit of
  51. native -> erts_internal:time_unit();
  52. perf_counter -> erts_internal:perf_counter_unit();
  53. nanosecond -> 1000 * 1000 * 1000;
  54. microsecond -> 1000 * 1000;
  55. millisecond -> 1000;
  56. second -> 1
  57. end,
  58. case Time < 0 of
  59. true -> (TU * Time - (FU - 1)) div FU;
  60. _ -> TU * Time div FU
  61. end
  62. catch
  63. _ : _ ->
  64. erlang:error(badarg, [Time, FromUnit, ToUnit])
  65. end.
  66. %% 单进程循环测试:LoopTimes是循环次数
  67. %% utTc:ts(LoopTimes, Module, Function, ArgsList).
  68. %% 多进程并发测试:SpawnProcessesCount是并发的进程数 LoopTimes是循环次数
  69. %% utTc:tm(ProcessesCount, LoopTimes, Module, Function, ArgsList).
  70. doTc(M, F, A) ->
  71. T1 = erlang:monotonic_time(),
  72. apply(M, F, A),
  73. T2 = erlang:monotonic_time(),
  74. cvrTimeUnit(T2 - T1, native, nanosecond).
  75. distribution(List, Aver) ->
  76. distribution(List, Aver, 0, 0).
  77. distribution([H | T], Aver, Greater, Less) ->
  78. case H > Aver of
  79. true ->
  80. distribution(T, Aver, Greater + 1, Less);
  81. false ->
  82. distribution(T, Aver, Greater, Less + 1)
  83. end;
  84. distribution([], _Aver, Greater, Less) ->
  85. {Greater, Less}.
  86. %% ===================================================================
  87. %% test: one process test N times
  88. %% ===================================================================
  89. ts(LoopTime, M, F, A) ->
  90. {Max, Min, Sum, Aver, Greater, Less} = loopTs(LoopTime, M, F, A, LoopTime, 0, 0, 0, []),
  91. io:format("=====================~n"),
  92. %io:format("execute Args:~p~n", [A]),
  93. io:format("execute Fun :~p~n", [F]),
  94. io:format("execute Mod :~p~n", [M]),
  95. io:format("execute LoopTime:~p~n", [LoopTime]),
  96. io:format("MaxTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Max), float_to_binary(Max / 1000000000, [{decimals, 6}, compact])]),
  97. io:format("MinTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Min), float_to_binary(Min / 1000000000, [{decimals, 6}, compact])]),
  98. io:format("SumTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Sum), float_to_binary(Sum / 1000000000, [{decimals, 6}, compact])]),
  99. io:format("AvgTime: ~10s(ns) ~10s(s)~n", [float_to_binary(Aver, [{decimals, 6}, compact]), float_to_binary(Aver / 1000000000, [{decimals, 6}, compact])]),
  100. io:format("Grar : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Greater), float_to_binary(Greater / LoopTime, [{decimals, 2}]), <<"%">>]),
  101. io:format("Less : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Less), float_to_binary(Less / LoopTime, [{decimals, 2}]), <<"%">>]),
  102. io:format("=====================~n").
  103. loopTs(0, _M, _F, _A, LoopTime, Max, Min, Sum, List) ->
  104. Aver = Sum / LoopTime,
  105. {Greater, Less} = distribution(List, Aver),
  106. {Max, Min, Sum, Aver, Greater, Less};
  107. loopTs(Index, M, F, A, LoopTime, Max, Min, Sum, List) ->
  108. Nanosecond = doTc(M, F, A),
  109. NewSum = Sum + Nanosecond,
  110. if
  111. Max == 0 ->
  112. NewMax = NewMin = Nanosecond;
  113. Max < Nanosecond ->
  114. NewMax = Nanosecond,
  115. NewMin = Min;
  116. Min > Nanosecond ->
  117. NewMax = Max,
  118. NewMin = Nanosecond;
  119. true ->
  120. NewMax = Max,
  121. NewMin = Min
  122. end,
  123. loopTs(Index - 1, M, F, A, LoopTime, NewMax, NewMin, NewSum, [Nanosecond | List]).
  124. %% ===================================================================
  125. %% Concurrency test: N processes each test one time
  126. %% ===================================================================
  127. tm(ProcCnt, LoopTime, M, F, A) ->
  128. loopSpawn(ProcCnt, M, F, A, self(), LoopTime),
  129. {Max, Min, Sum, Aver, Greater, Less} = collector(ProcCnt, 0, 0, 0, ProcCnt, []),
  130. io:format("=====================~n"),
  131. %io:format("execute Args:~p~n", [A]),
  132. io:format("execute Fun :~p~n", [F]),
  133. io:format("execute Mod :~p~n", [M]),
  134. io:format("execute LoopTime:~p~n", [LoopTime]),
  135. io:format("execute ProcCnts:~p~n", [ProcCnt]),
  136. io:format("MaxTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Max), float_to_binary(Max / 1000000000, [{decimals, 6}, compact])]),
  137. io:format("MinTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Min), float_to_binary(Min / 1000000000, [{decimals, 6}, compact])]),
  138. io:format("SumTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Sum), float_to_binary(Sum / 1000000000, [{decimals, 6}, compact])]),
  139. io:format("AvgTime: ~10s(ns) ~10s(s)~n", [float_to_binary(Aver, [{decimals, 6}, compact]), float_to_binary(Aver / 1000000000, [{decimals, 6}, compact])]),
  140. io:format("Grar : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Greater), float_to_binary(Greater / LoopTime, [{decimals, 2}]), <<"%">>]),
  141. io:format("Less : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Less), float_to_binary(Less / LoopTime, [{decimals, 2}]), <<"%">>]),
  142. io:format("=====================~n").
  143. loopSpawn(0, _, _, _, _, _) ->
  144. ok;
  145. loopSpawn(ProcCnt, M, F, A, CollectorPid, LoopTime) ->
  146. spawn_link(fun() -> worker(LoopTime, M, F, A, CollectorPid) end),
  147. loopSpawn(ProcCnt - 1, M, F, A, CollectorPid, LoopTime).
  148. collector(0, Max, Min, Sum, ProcCnt, List) ->
  149. Aver = Sum / ProcCnt,
  150. {Greater, Less} = distribution(List, Aver),
  151. {Max, Min, Sum, Aver, Greater, Less};
  152. collector(Index, Max, Min, Sum, ProcCnt, List) ->
  153. receive
  154. {result, Nanosecond} ->
  155. NewSum = Sum + Nanosecond,
  156. if
  157. Max == 0 ->
  158. NewMax = NewMin = Nanosecond;
  159. Max < Nanosecond ->
  160. NewMax = Nanosecond,
  161. NewMin = Min;
  162. Min > Nanosecond ->
  163. NewMax = Max,
  164. NewMin = Nanosecond;
  165. true ->
  166. NewMax = Max,
  167. NewMin = Min
  168. end,
  169. collector(Index - 1, NewMax, NewMin, NewSum, ProcCnt, [Nanosecond | List])
  170. after 1800000 ->
  171. io:format("execute time out~n"),
  172. ok
  173. end.
  174. worker(LoopTime, M, F, A, CollectorPid) ->
  175. SumTime = loopTm(LoopTime, M, F, A, 0),
  176. CollectorPid ! {result, SumTime}.
  177. loopTm(0, _, _, _, SumTime) ->
  178. SumTime;
  179. loopTm(LoopTime, M, F, A, SumTime) ->
  180. Microsecond = doTc(M, F, A),
  181. loopTm(LoopTime - 1, M, F, A, SumTime + Microsecond).
  182. test(N) ->
  183. M1 = erlang:monotonic_time(),
  184. timer:sleep(N),
  185. M2 = erlang:monotonic_time(),
  186. Time = cvrTimeUnit(M2 - M1, native, nanosecond),
  187. io:format("IMY******************111 ~p~n", [Time]),
  188. S1 = erlang:system_time(nanosecond),
  189. timer:sleep(N),
  190. S2 = erlang:system_time(nanosecond),
  191. io:format("IMY******************222 ~p~n", [S2 - S1]).