Guest User

Untitled

a guest
Jul 27th, 2016
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.81 KB | None | 0 0
  1. -module(test).
  2. -compile(export_all).
  3. %% API
  4.  
  5. -compile({inline, [ insert/2
  6. , merge/2
  7. ]}).
  8.  
  9. insert(E, []) -> [E];
  10. insert(E, [E2|_] = H) when E =< E2 -> [E, H];
  11. insert(E, [E2|H]) -> [E2, [E]|H].
  12.  
  13. merge(H1, []) -> H1;
  14. merge([E1|H1], [E2|_]=H2) when E1 =< E2 -> [E1, H2|H1];
  15. merge(H1, [E2|H2]) -> [E2, H1|H2].
  16.  
  17. merge_pairs([]) -> [];
  18. merge_pairs([H]) -> H;
  19. merge_pairs([A, B|T]) -> merge(merge(A, B), merge_pairs(T)).
  20.  
  21. run_pheap(List, Num) ->
  22. run_pheap(List, Num, []).
  23.  
  24. run_pheap(List, 0, Heap) ->
  25. pheap_full(List, Heap);
  26. run_pheap([], 0, Heap) ->
  27. finish(Heap, []);
  28. run_pheap([{Y, X, _} = H|T], N, Heap) ->
  29. run_pheap(T, N-1, insert({{X, Y}, H}, Heap)).
  30.  
  31. pheap_full([], Heap) ->
  32. finish(Heap, []);
  33. pheap_full([{Y, X, _} = H|T], [{K, _}|HeapT] = Heap) ->
  34. case {X, Y} of
  35. N when N > K ->
  36. pheap_full(T, insert({N, H}, merge_pairs(HeapT)));
  37. _ ->
  38. pheap_full(T, Heap)
  39. end.
  40.  
  41. finish([], Acc) -> Acc;
  42. finish([{_, H}|T], Acc) ->
  43. finish(merge_pairs(T), [H|Acc]).
  44.  
  45. run_all_sorted_sublist(List, Num) ->
  46. L = [ {{X, Y}, Z} || {Y, X, _} = Z <- List],
  47. [ X || {_, X} <- lists:sublist(lists:reverse(lists:sort(L)), Num) ].
  48.  
  49. run_gb_trees(List, Num) ->
  50. run_gb_trees(List, Num, gb_trees:empty()).
  51.  
  52. run_gb_trees([], _Num, Acc) ->
  53. lists:foldl(fun({Key1, Key2, Key3}, Sum) -> [{Key2, Key1, Key3}|Sum] end, [], gb_trees:keys(Acc));
  54. run_gb_trees([{Key1, Key2, Key3}|List], Num, Acc) ->
  55. NewKey = {Key2, Key1, Key3},
  56. NewAcc =
  57. case gb_trees:size(Acc) < Num of
  58. true ->
  59. gb_trees:insert(NewKey, 0, Acc);
  60. false ->
  61. {Smallest,_} = gb_trees:smallest(Acc),
  62. case Smallest < NewKey of
  63. true ->
  64. Acc2 = gb_trees:delete(Smallest, Acc),
  65. gb_trees:insert(NewKey, 0, Acc2);
  66. false ->
  67. Acc
  68. end
  69. end,
  70. run_gb_trees(List, Num, NewAcc).
  71.  
  72. run_ordered_set_ets(List, Num) ->
  73. run_ordered_set_ets(List, Num,
  74. {0, ets:new(t, [ordered_set, public, {keypos, 2}])}).
  75.  
  76. run_ordered_set_ets([], _Num, {_, Table}) ->
  77. R = lists:reverse(ets:tab2list(Table)),
  78. ets:delete(Table),
  79. R;
  80. run_ordered_set_ets([{_, K, _} = H | T], Num, {I, Table}) ->
  81. case I < Num of
  82. true ->
  83. ets:insert(Table, H);
  84. false ->
  85. SmallestK = ets:first(Table),
  86. case K > SmallestK of
  87. true ->
  88. ets:delete(Table, SmallestK),
  89. ets:insert(Table, H);
  90. false ->
  91. ok
  92. end
  93. end,
  94. run_ordered_set_ets(T, Num, {I + 1, Table}).
  95.  
  96. run_small_to_big_order_list(List, Num) ->
  97. run_small_to_big_order_list(List, Num, 0, []).
  98.  
  99. run_small_to_big_order_list([], _Num, _, Acc) ->
  100. lists:foldl(fun({Key1, Key2, Key3}, Sum) -> [{Key2, Key1, Key3}|Sum] end, [], Acc);
  101. run_small_to_big_order_list([{Key1, Key2, Key3}|List], Num, Len, Acc) ->
  102. NewKey = {Key2, Key1, Key3},
  103. {NewLen, NewAcc} =
  104. case Len < Num of
  105. true ->
  106. {Len + 1, lists:sort([NewKey|Acc])};
  107. false ->
  108. [Smallest|Acc2] = Acc,
  109. case Smallest < NewKey of
  110. true ->
  111. {Len, lists:sort([NewKey|Acc2])};
  112. false ->
  113. {Len, Acc}
  114. end
  115. end,
  116. run_small_to_big_order_list(List, Num, NewLen, NewAcc).
  117.  
  118. run_small_to_big_order_list_v2(List, Num) ->
  119. run_small_to_big_order_list_v2(List, Num, fun({X2, X1, _}, {Y2, Y1, _})
  120. -> {X1, X2} =< {Y1, Y2} end, 0, []).
  121.  
  122. run_small_to_big_order_list_v2([], _, _, _, Acc) ->
  123. lists:reverse(Acc);
  124. run_small_to_big_order_list_v2([NewKey|List], Num, Fun, Len, Acc) ->
  125. {NewLen, NewAcc} =
  126. if Len < Num -> {Len + 1, insert(NewKey, Acc, Fun)};
  127. true ->
  128. [Smallest|Acc2] = Acc,
  129. case Fun(Smallest,NewKey) of
  130. true -> {Len, insert(NewKey, Acc2, Fun)};
  131. false -> {Len, Acc}
  132. end
  133. end,
  134. run_small_to_big_order_list_v2(List, Num, Fun, NewLen, NewAcc).
  135.  
  136. insert(K, [], _) -> [K];
  137. insert(K, [H|T], Fun) ->
  138. case Fun(K, H) of
  139. true -> [K, H|T];
  140. false -> [H|insert(K, T, Fun)]
  141. end.
  142.  
  143. run_big_to_small_order_list(List, Num) ->
  144. run_big_to_small_order_list(List, Num, 0, []).
  145.  
  146. run_big_to_small_order_list([], _Num, _, Acc) ->
  147. Acc;
  148. run_big_to_small_order_list([Key|List], Num, Len, Acc) ->
  149. {NewLen, NewAcc} =
  150. case Len < Num of
  151. true ->
  152. {Len + 1, lists:sort(fun({X2, X1, _}, {Y2, Y1, _}) -> {X1, X2} > {Y1, Y2} end, [Key|Acc])};
  153. false ->
  154. Smallest = lists:last(Acc),
  155. case Smallest < Key of
  156. true ->
  157. Acc2 = lists:sublist(Acc, Len - 1),
  158. {Len, lists:sort(fun({X2, X1, _}, {Y2, Y1, _}) -> {X1, X2} > {Y1, Y2} end, [Key|Acc2])};
  159. false ->
  160. {Len, Acc}
  161. end
  162. end,
  163. run_big_to_small_order_list(List, Num, NewLen, NewAcc).
  164.  
  165. test() ->
  166. [ test(TotalNum, TopNum)
  167. || TotalNum <- [5000, 10000, 15000, 20000, 25000],
  168. TopNum <- [20, 30, 40, 50, 60, 70]].
  169.  
  170. test_big() ->
  171. [ test(TotalNum, TopNum)
  172. || TotalNum <- [25000],
  173. TopNum <- [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200]].
  174.  
  175. %% Test
  176. test(TotalNum, TopNum) ->
  177. List = prepared_random_list(TotalNum),
  178. %io:format("~p~n", [List]),
  179. Self = self(),
  180. L = lists:keysort(2,
  181. [ receive {Pid, X} -> X end
  182. || {F, Type} <-
  183. [{run_all_sorted_sublist, all_sorted_sublist________},
  184. {run_gb_trees, gb_tree___________________},
  185. {run_small_to_big_order_list, small_to_big_order_list___},
  186. {run_big_to_small_order_list, big_to_small_order_list___},
  187. {run_small_to_big_order_list_v2, small_to_big_order_list_v2},
  188. {run_pheap, pheap_____________________},
  189. {run_ordered_set_ets, ordered_set_ets___________}],
  190. Pid <- [spawn_link(fun() ->
  191. {Time, Result} = timer:tc(?MODULE, F, [List, TopNum]),
  192. Self ! {self(), {Type, Time, Result}}
  193. end)]
  194. ]),
  195. [{_, Time1, _}|_] = L,
  196. [_] = lists:ukeysort(3, L),
  197. {{TotalNum, TopNum}, [{Type, Time, Time/Time1*100}
  198. || {Type, Time, _} <- L]}.
  199.  
  200. prepared_random_list(TotalNum) ->
  201. [ {X, X+1, X+2}
  202. || {_, X} <- lists:sort(
  203. [ {rand:uniform(), X}
  204. || X <- lists:seq(1, TotalNum) ])
  205. ].
Add Comment
Please, Sign In to add comment