1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.examples.jmh.euclidean;
18
19 import java.util.concurrent.TimeUnit;
20
21 import org.apache.commons.geometry.euclidean.threed.RegionBSPTree3D;
22 import org.apache.commons.geometry.euclidean.threed.Vector3D;
23 import org.apache.commons.geometry.euclidean.threed.shape.Sphere;
24 import org.apache.commons.numbers.core.Precision;
25 import org.apache.commons.rng.UniformRandomProvider;
26 import org.apache.commons.rng.simple.RandomSource;
27 import org.openjdk.jmh.annotations.Benchmark;
28 import org.openjdk.jmh.annotations.BenchmarkMode;
29 import org.openjdk.jmh.annotations.Fork;
30 import org.openjdk.jmh.annotations.Level;
31 import org.openjdk.jmh.annotations.Measurement;
32 import org.openjdk.jmh.annotations.Mode;
33 import org.openjdk.jmh.annotations.OutputTimeUnit;
34 import org.openjdk.jmh.annotations.Param;
35 import org.openjdk.jmh.annotations.Scope;
36 import org.openjdk.jmh.annotations.Setup;
37 import org.openjdk.jmh.annotations.State;
38 import org.openjdk.jmh.annotations.Warmup;
39
40
41
42 @BenchmarkMode(Mode.AverageTime)
43 @OutputTimeUnit(TimeUnit.NANOSECONDS)
44 @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
45 @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
46 @Fork(value = 1, jvmArgs = {"-server", "-Xms512M", "-Xmx512M"})
47 public class SpherePerformance {
48
49
50 private static final double EPS = 1e-10;
51
52
53 private static final double MIN_VALUE = 1e-1;
54
55
56 private static final double MAX_VALUE = 1e2;
57
58
59
60 @State(Scope.Thread)
61 public static class RandomSphere {
62
63
64 private Sphere sphere;
65
66
67 @Setup(Level.Iteration)
68 public void setup() {
69 sphere = randomSphere(RandomSource.create(RandomSource.XO_RO_SHI_RO_128_PP));
70 }
71
72
73
74
75 public Sphere getSphere() {
76 return sphere;
77 }
78 }
79
80
81
82 @State(Scope.Thread)
83 public static class ToTreeInput {
84
85
86 @Param({"3", "4", "5"})
87 private int subdivisions;
88
89
90
91
92 public int getSubdivisions() {
93 return subdivisions;
94 }
95 }
96
97
98
99 @State(Scope.Thread)
100 public static class ToTreeInstance extends ToTreeInput {
101
102
103 private RegionBSPTree3D tree;
104
105
106 @Setup(Level.Iteration)
107 public void setup() {
108 final Sphere sphere = randomSphere(RandomSource.create(RandomSource.XO_RO_SHI_RO_128_PP));
109
110 tree = sphere.toTree(getSubdivisions());
111 }
112
113
114
115
116 public RegionBSPTree3D getTree() {
117 return tree;
118 }
119 }
120
121
122
123
124
125
126 private static Sphere randomSphere(final UniformRandomProvider rand) {
127 final Vector3D center = Vector3D.of(nextDouble(rand), nextDouble(rand), nextDouble(rand));
128 final double radius = nextDouble(rand);
129
130 return Sphere.from(center, radius, Precision.doubleEquivalenceOfEpsilon(EPS));
131 }
132
133
134
135
136
137 private static double nextDouble(final UniformRandomProvider rand) {
138 return (rand.nextDouble() * (MAX_VALUE - MIN_VALUE)) + MIN_VALUE;
139 }
140
141
142
143
144
145
146 @Benchmark
147 public RegionBSPTree3D toTreeCreation(final RandomSphere randomSphere, final ToTreeInput toTreeInput) {
148 final Sphere sphere = randomSphere.getSphere();
149 final int subdivisions = toTreeInput.getSubdivisions();
150
151 return sphere.toTree(subdivisions);
152 }
153
154
155
156
157
158
159 @Benchmark
160 public double toTreeSize(final ToTreeInstance toTreeInstance) {
161 final RegionBSPTree3D tree = toTreeInstance.getTree();
162
163 return tree.getSize();
164 }
165 }