Advertisement
Guest User

Untitled

a guest
Sep 30th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.80 KB | None | 0 0
  1. import javafx.util.Pair;
  2.  
  3. import java.util.*;
  4. import java.util.function.Consumer;
  5. import java.util.stream.Collectors;
  6.  
  7. import static java.lang.Math.max;
  8.  
  9. public class Main {
  10.  
  11. private static final int FRACTIONAL_DENOMINATOR_TO_KEEP = 1000;
  12.  
  13. /**
  14. * The predicate that determines if an item shall be removed from the list.
  15. * In this example we are looking for extreme cases, so we chose a predicate
  16. * that removes all but every 1000 items.
  17. *
  18. * @param i
  19. * @return true iff the item i shall be removed
  20. */
  21. private static boolean predicate(int i) {
  22. return i % FRACTIONAL_DENOMINATOR_TO_KEEP != 0;
  23. }
  24.  
  25. public static void main(String[] args) {
  26. warmUpJit();
  27. computeAll();
  28. }
  29.  
  30. private static void warmUpJit() {
  31. computeComparativeGraphData(1000, 10_000, 1000); // compute and throw away results
  32. }
  33.  
  34. private static void computeAll() {
  35. final int step = FRACTIONAL_DENOMINATOR_TO_KEEP;
  36. final int start = step;
  37. final int end = 150 * step;
  38.  
  39. final Map<Integer, Pair<Long, Long>> results = computeComparativeGraphData(start, end, step);
  40. printResults("Actual times", results);
  41. System.out.println(" --- 8< ---");
  42. printResults("Normalized times", normalize(results));
  43. }
  44.  
  45. private static void printResults(String title, Map<Integer, Pair<Long, Long>> results) {
  46. System.out.println(title);
  47. System.out.println("Length, Iterator, removeIf");
  48.  
  49. results.entrySet().stream().sorted((e1, e2) -> e1.getKey() - e2.getKey())
  50. .forEach(entry -> {
  51. final Pair<Long, Long> p = entry.getValue();
  52. System.out.println("" + entry.getKey() + ", " +
  53. p.getKey() + ", " +
  54. p.getValue()
  55. );
  56. });
  57. }
  58.  
  59. /**
  60. * Normalize value pairs to make max values equal.
  61. *
  62. * @param results a Map from Integer to a Pair of Longs representing
  63. * execution times for two different designs.
  64. *
  65. * @return a new map with normalized values, where max values are equal
  66. */
  67. private static Map<Integer, Pair<Long, Long>> normalize(Map<Integer, Pair<Long, Long>> results) {
  68. final Pair<Long, Long> maxValues = results.values().stream().
  69. reduce(new Pair<>(0L, 0L),
  70. (s, v) -> new Pair<>(
  71. max(s.getKey(), v.getKey()),
  72. max(s.getValue(), v.getValue())
  73. )
  74. );
  75.  
  76. final double maxInteratorTime = maxValues.getKey().doubleValue();
  77. final double maxRemoveIfTime = maxValues.getValue().doubleValue();
  78. double factor = maxInteratorTime / maxRemoveIfTime;
  79.  
  80. System.out.println("Iterator is " + factor + " times slower than removeIf()");
  81.  
  82. double scalingFactor = factor * 0.5; // we scale the faster times up half the way
  83.  
  84. return results.entrySet().stream().
  85. collect(Collectors.toMap(
  86. Map.Entry::getKey,
  87. p -> new Pair<>(
  88. p.getValue().getKey(),
  89. (long) (p.getValue().getValue() * scalingFactor)
  90. ))
  91. );
  92. }
  93.  
  94. /**
  95. * Create a map from array size to a pair of execution times - (iterator, removeIf)
  96. *
  97. * @param start start array size
  98. * @param end ending array size
  99. * @param step step between sizes
  100. * @return a mapping (array size) -> (iterator execution time, removeIf execution time)
  101. */
  102. private static Map<Integer, Pair<Long, Long>> computeComparativeGraphData(int start, int end, int step) {
  103. Map<Integer, Pair<Long, Long>> results = new HashMap<>();
  104. for (int n = start; n <= end; n += step) {
  105. results.put(n, new Pair<>(timeIterator(n), timeRemoveIf(n)));
  106. }
  107. return results;
  108. }
  109.  
  110.  
  111. private static long timeRemoveIf(int n) {
  112. return timeMany(n, l -> l.removeIf(i -> predicate(i)));
  113. }
  114.  
  115. private static long timeIterator(int n) {
  116. return timeMany(n, l -> {
  117. for (Iterator<Integer> it = l.iterator(); it.hasNext();) {
  118. if (predicate(it.next())) {
  119. it.remove();
  120. }
  121. }
  122. }
  123. );
  124. }
  125.  
  126. /**
  127. * Create and fill an array, then apply a consumer to all elements and measure average execution time
  128. *
  129. * @param size the size of the array to be created
  130. * @param filter the list consumer to be evaluated
  131. * @return average execution time in some unit of time (
  132. */
  133. private static long timeMany(int size, Consumer<List<Integer>> filter) {
  134. final int skipped = 5; // extreme values to be removed before averaging
  135. final int n = skipped * 8; // total number of runs
  136.  
  137. long[] results = new long[n];
  138. for (int i=0; i<n; i++) {
  139. results[i] = timeOnce(buildList(size), filter);
  140. }
  141. Arrays.sort(results);
  142.  
  143. long tailSum = Arrays.stream(results).skip(n - skipped).sum();
  144. long midAndTailSum = Arrays.stream(results).skip(skipped).sum();
  145.  
  146. return midAndTailSum - tailSum;
  147. }
  148.  
  149. private static List<Integer> buildList(int size) {
  150. ArrayList<Integer> numbers = new ArrayList<>(size);
  151. for (int i=0; i < size; i++) {
  152. numbers.add(i);
  153. }
  154. return numbers;
  155. }
  156.  
  157. private static <T> long timeOnce(List<T> list, Consumer<List<T>> filter) {
  158. int lengthBefore = list.size();
  159. System.gc();
  160. long start = System.nanoTime();
  161. filter.accept(list);
  162. long time = System.nanoTime() - start;
  163. assert list.size() == lengthBefore / FRACTIONAL_DENOMINATOR_TO_KEEP;
  164. return time;
  165. }
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement