fork(1) download
  1. import java.util.*;
  2. import java.lang.*;
  3. import java.io.*;
  4. import java.text.*;
  5. import java.util.function.*;
  6. import static java.lang.Math.*;
  7.  
  8. class Util {
  9. static IllegalArgumentException badArgf(String fmt, Object... args) {
  10. return new IllegalArgumentException(String.format(fmt, args));
  11. }
  12.  
  13. static final DecimalFormat humanFloatFormat = new DecimalFormat("#.###");
  14.  
  15. static String humanFloat(double x) {
  16. return humanFloatFormat.format(x);
  17. }
  18.  
  19. static String trace(Exception e) {
  20. e.printStackTrace(new PrintWriter(sw));
  21. return sw.toString();
  22. }
  23. }
  24.  
  25. class Vec2 {
  26. public final double x, y;
  27. public Vec2(double x, double y) { this.x = x; this.y = y; }
  28. public static Vec2 Vec2(double x, double y) { return new Vec2(x, y); }
  29. public Vec2 add(Vec2 b) { return Vec2(x + b.x, y + b.y); }
  30. public Vec2 sub(Vec2 b) { return Vec2(x - b.x, y - b.y); }
  31. public Vec2 mul(Vec2 b) { return Vec2(x * b.x, y * b.y); }
  32. public Vec2 mul(double b) { return Vec2(x * b, y * b); }
  33. public Vec2 div(Vec2 b) { return Vec2(x / b.x, y / b.y); }
  34. public Vec2 div(double b) { return Vec2(x / b, y / b); }
  35. @Override public String toString() { return String.format("(%s, %s)", Util.humanFloat(x), Util.humanFloat(y)); }
  36. public Vec2 min(Vec2 b) { return Vec2(Math.min(x, b.x), Math.min(y, b.y)); }
  37. public Vec2 max(Vec2 b) { return Vec2(Math.max(x, b.x), Math.max(y, b.y)); }
  38. }
  39.  
  40. class AABB {
  41. public final Vec2 a, b;
  42. public AABB(Vec2 a, Vec2 b) { this.a = a; this.b = b; }
  43. public static AABB AABB(Vec2 a, Vec2 b) { return new AABB(a, b); }
  44. @Override public String toString() { return String.format("A = %s, B = %s", a, b); }
  45.  
  46. public static AABB bound(int count, IntFunction<AABB> ithBB) {
  47. if (count <= 0) throw Util.badArgf("AABB.bound: count = %d.", count);
  48. var bb = ithBB.apply(0);
  49. Vec2 a = bb.a, b = bb.b;
  50. for (int i = 1; i < count; i++) {
  51. bb = ithBB.apply(i);
  52. a = a.min(bb.a);
  53. b = b.max(bb.b);
  54. }
  55. return AABB(a, b);
  56. }
  57.  
  58. public static AABB bound(List<AABB> bbs) {
  59. if (bbs.size() == 0) throw Util.badArgf("AABB.bound: count = %d.", bbs.size());
  60. var bb = bbs.get(0);
  61. Vec2 a = bb.a, b = bb.b;
  62. for (int i = 1; i < bbs.size(); i++) {
  63. bb = bbs.get(i);
  64. a = a.min(bb.a);
  65. b = b.max(bb.b);
  66. }
  67. return AABB(a, b);
  68. }
  69.  
  70. public static AABB bound(Iterator<AABB> bbs) {
  71. if (!bbs.hasNext()) throw Util.badArgf("AABB.bound: no items.");
  72. var bb = bbs.next();
  73. Vec2 a = bb.a, b = bb.b;
  74. while (bbs.hasNext()) {
  75. bb = bbs.next();
  76. a = a.min(bb.a);
  77. b = b.max(bb.b);
  78. }
  79. return AABB(a, b);
  80. }
  81. }
  82.  
  83. class MyPreciousObject {
  84. AABB bb;
  85. Vec2 pos;
  86. String name;
  87. Object someOtherData;
  88.  
  89. public MyPreciousObject(AABB bb) {
  90. this.bb = bb;
  91. }
  92. }
  93.  
  94. class Ideone
  95. {
  96. static double benchmark(String title, Supplier payload) {
  97. return benchmark(title, payload, -1);
  98. }
  99.  
  100. static double benchmark(String title, Supplier payload, double reference) {
  101. long start = System.nanoTime();
  102. var payloadResult = payload.get();
  103. double time = (System.nanoTime() - start) * 1e-9;
  104. // использовать payloadResult желательно даже без соответствующего %s, а то мало ли СОПТИМИЗИРУЕТСЯ при неиспользовании.
  105. System.out.println(String.format(
  106. "%s: %.2f s%s%s",
  107. title, time, reference >= 0 ? String.format(" (%s)", judgement(time, reference)) : "",
  108. payloadResult != null ? String.format("\n%s\n", payloadResult) : ""));
  109. return time;
  110. }
  111.  
  112. static String judgement(double time, double refTime) {
  113. final double absThreshold = 0.1, relThreshold = .1;
  114.  
  115. return time <= absThreshold || refTime <= absThreshold ?
  116. String.format("can't judge, min. required time is %.1f s", absThreshold) :
  117. Math.max(time, refTime) > (1 + relThreshold) * Math.min(time, refTime) ?
  118. String.format("%.0f%% %s",
  119. Math.abs((time < refTime ? refTime / time : time / refTime) - 1) * 100,
  120. time < refTime ? "faster" : "slower") :
  121. String.format("no observable difference, min. %.0f%% required", relThreshold * 100);
  122. }
  123.  
  124. static void benchmark() {
  125. var objs = new ArrayList<MyPreciousObject>();
  126. var rand = new Random(1);
  127. for (int i = 0; i < 1_000_000; i++) {
  128. Vec2 a = Vec2.Vec2(rand.nextDouble(), rand.nextDouble()).mul(100);
  129. objs.add(new MyPreciousObject(
  130. AABB.AABB(a, a.add(Vec2.Vec2(rand.nextDouble(), rand.nextDouble()).mul(10)))
  131. ));
  132. }
  133. var bbList = new ArrayList<AABB>();
  134.  
  135. final int TRIALS = 3, AMPLIFY = 50;
  136. for (int iTrial = 0; iTrial < TRIALS; iTrial++) {
  137. System.out.printf("%s--- TRIAL %d/%d ---\n", iTrial > 0 ? "\n" : "", 1 + iTrial, TRIALS);
  138. var ref = benchmark("bound(List<AABB>)", () -> {
  139. AABB result = null;
  140. for (int iAmp = 0; iAmp < AMPLIFY; iAmp++) {
  141. bbList.clear();
  142. bbList.ensureCapacity(objs.size());
  143. for (int i = 0; i < objs.size(); i++)
  144. bbList.add(objs.get(i).bb);
  145. result = AABB.bound(bbList);
  146. }
  147. return result;
  148. });
  149.  
  150. benchmark("bound(int -> AABB)", () -> {
  151. AABB result = null;
  152. for (int iAmp = 0; iAmp < AMPLIFY; iAmp++)
  153. result = AABB.bound(objs.size(), i -> objs.get(i).bb);
  154. return result;
  155. }, ref);
  156.  
  157. benchmark("bound(List<MyPreciousObject>.map(obj -> AABB).iterator)", () -> {
  158. AABB result = null;
  159. for (int iAmp = 0; iAmp < AMPLIFY; iAmp++)
  160. result = AABB.bound(objs.stream().map(obj -> obj.bb).iterator());
  161. return result;
  162. }, ref);
  163. }
  164. }
  165.  
  166. public static void main (String[] args) throws java.lang.Exception
  167. {
  168. try {
  169. benchmark();
  170. } catch (Exception e) {
  171. System.out.println(Util.trace(e));
  172. }
  173. }
  174. }
Success #stdin #stdout 14.4s 250264KB
stdin
Standard input is empty
stdout
--- TRIAL 1/3 ---
bound(List<AABB>): 1.46 s
A = (0, 0), B = (109.956, 109.954)

bound(int -> AABB): 1.12 s (31% faster)
A = (0, 0), B = (109.956, 109.954)

bound(List<MyPreciousObject>.map(obj -> AABB).iterator): 2.23 s (53% slower)
A = (0, 0), B = (109.956, 109.954)


--- TRIAL 2/3 ---
bound(List<AABB>): 1.38 s
A = (0, 0), B = (109.956, 109.954)

bound(int -> AABB): 1.03 s (33% faster)
A = (0, 0), B = (109.956, 109.954)

bound(List<MyPreciousObject>.map(obj -> AABB).iterator): 2.14 s (56% slower)
A = (0, 0), B = (109.956, 109.954)


--- TRIAL 3/3 ---
bound(List<AABB>): 1.35 s
A = (0, 0), B = (109.956, 109.954)

bound(int -> AABB): 1.04 s (30% faster)
A = (0, 0), B = (109.956, 109.954)

bound(List<MyPreciousObject>.map(obj -> AABB).iterator): 2.13 s (57% slower)
A = (0, 0), B = (109.956, 109.954)