Skip to content

Commit fdd8bf7

Browse files
flarjohnmccutchan
authored andcommitted
Reuse temp variables in Aabb2.transform methods. (google#211)
* Reuse temp variables in Aabb2.transform methods. Improve consistency in avoiding public getters in a number of methods. Add benchmarks for affected code to ensure positive performance impact. Aabb2.transform is about 11% faster with these changes. Aabb2.rotate is about 17% faster with these changes. The rest of the changes had no measurable benchmark impact, but improve consistency in the source base. (Added .idea directory from IntelliJ/Android Studio to .gitignore) * Update 64-bit sources to match. * Ran dartfmt on files. * Apply same optimization to Aabb3 methods. Aabb3.transform is about 11% faster with the change. Aabb3.rotate is about 14% faster with the change.
1 parent 4b6d6a8 commit fdd8bf7

File tree

8 files changed

+360
-118
lines changed

8 files changed

+360
-118
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ pubspec.lock
66
.pub
77
.packages
88
.dart_tool
9+
.idea

benchmark/matrix_bench.dart

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
library vector_math_matrix_bench;
66

7+
import 'dart:math' as math;
78
import 'dart:typed_data';
89
import 'package:vector_math/vector_math.dart';
910
import 'package:vector_math/vector_math_operations.dart';
@@ -101,10 +102,238 @@ class ViewMatrixBenchmark extends BenchmarkBase {
101102
}
102103
}
103104

105+
class Aabb2TransformBenchmark extends BenchmarkBase {
106+
Aabb2TransformBenchmark() : super("aabb2Transform");
107+
108+
static final Matrix3 M = Matrix3.rotationZ(math.pi / 4);
109+
static final Vector2 P1 = Vector2(10.0, 10.0);
110+
static final Vector2 P2 = Vector2(20.0, 30.0);
111+
static final Vector2 P3 = Vector2(100.0, 50.0);
112+
static final Aabb2 B1 = Aabb2.minMax(P1, P2);
113+
static final Aabb2 B2 = Aabb2.minMax(P1, P3);
114+
static final Aabb2 B3 = Aabb2.minMax(P2, P3);
115+
static final Aabb2 temp = Aabb2();
116+
117+
static void main() {
118+
Aabb2TransformBenchmark().report();
119+
}
120+
121+
@override
122+
void run() {
123+
for (int i = 0; i < 100; i++) {
124+
temp.copyFrom(B1);
125+
temp.transform(M);
126+
temp.copyFrom(B2);
127+
temp.transform(M);
128+
temp.copyFrom(B3);
129+
temp.transform(M);
130+
}
131+
}
132+
}
133+
134+
class Aabb2RotateBenchmark extends BenchmarkBase {
135+
Aabb2RotateBenchmark() : super("aabb2Rotate");
136+
137+
static final Matrix3 M = Matrix3.rotationZ(math.pi / 4);
138+
static final Vector2 P1 = Vector2(10.0, 10.0);
139+
static final Vector2 P2 = Vector2(20.0, 30.0);
140+
static final Vector2 P3 = Vector2(100.0, 50.0);
141+
static final Aabb2 B1 = Aabb2.minMax(P1, P2);
142+
static final Aabb2 B2 = Aabb2.minMax(P1, P3);
143+
static final Aabb2 B3 = Aabb2.minMax(P2, P3);
144+
static final Aabb2 temp = Aabb2();
145+
146+
static void main() {
147+
Aabb2RotateBenchmark().report();
148+
}
149+
150+
@override
151+
void run() {
152+
for (int i = 0; i < 100; i++) {
153+
temp.copyFrom(B1);
154+
temp.rotate(M);
155+
temp.copyFrom(B2);
156+
temp.rotate(M);
157+
temp.copyFrom(B3);
158+
temp.rotate(M);
159+
}
160+
}
161+
}
162+
163+
class Aabb3TransformBenchmark extends BenchmarkBase {
164+
Aabb3TransformBenchmark() : super("aabb3Transform");
165+
166+
static final Matrix4 M = Matrix4.rotationZ(math.pi / 4);
167+
static final Vector3 P1 = Vector3(10.0, 10.0, 0.0);
168+
static final Vector3 P2 = Vector3(20.0, 30.0, 1.0);
169+
static final Vector3 P3 = Vector3(100.0, 50.0, 10.0);
170+
static final Aabb3 B1 = Aabb3.minMax(P1, P2);
171+
static final Aabb3 B2 = Aabb3.minMax(P1, P3);
172+
static final Aabb3 B3 = Aabb3.minMax(P2, P3);
173+
static final Aabb3 temp = Aabb3();
174+
175+
static void main() {
176+
Aabb3TransformBenchmark().report();
177+
}
178+
179+
@override
180+
void run() {
181+
for (int i = 0; i < 100; i++) {
182+
temp.copyFrom(B1);
183+
temp.transform(M);
184+
temp.copyFrom(B2);
185+
temp.transform(M);
186+
temp.copyFrom(B3);
187+
temp.transform(M);
188+
}
189+
}
190+
}
191+
192+
class Aabb3RotateBenchmark extends BenchmarkBase {
193+
Aabb3RotateBenchmark() : super("aabb3Rotate");
194+
195+
static final Matrix4 M = Matrix4.rotationZ(math.pi / 4);
196+
static final Vector3 P1 = Vector3(10.0, 10.0, 0.0);
197+
static final Vector3 P2 = Vector3(20.0, 30.0, 1.0);
198+
static final Vector3 P3 = Vector3(100.0, 50.0, 10.0);
199+
static final Aabb3 B1 = Aabb3.minMax(P1, P2);
200+
static final Aabb3 B2 = Aabb3.minMax(P1, P3);
201+
static final Aabb3 B3 = Aabb3.minMax(P2, P3);
202+
static final Aabb3 temp = Aabb3();
203+
204+
static void main() {
205+
Aabb3RotateBenchmark().report();
206+
}
207+
208+
@override
209+
void run() {
210+
for (int i = 0; i < 100; i++) {
211+
temp.copyFrom(B1);
212+
temp.rotate(M);
213+
temp.copyFrom(B2);
214+
temp.rotate(M);
215+
temp.copyFrom(B3);
216+
temp.rotate(M);
217+
}
218+
}
219+
}
220+
221+
class Matrix3DeterminantBenchmark extends BenchmarkBase {
222+
Matrix3DeterminantBenchmark() : super("Matrix3.determinant");
223+
224+
final Matrix3 MX = Matrix3.rotationX(math.pi / 4);
225+
final Matrix3 MY = Matrix3.rotationY(math.pi / 4);
226+
final Matrix3 MZ = Matrix3.rotationZ(math.pi / 4);
227+
228+
static void main() {
229+
Matrix3DeterminantBenchmark().report();
230+
}
231+
232+
@override
233+
void run() {
234+
for (int i = 0; i < 800; i++) {
235+
MX.determinant();
236+
MY.determinant();
237+
MZ.determinant();
238+
}
239+
}
240+
}
241+
242+
class Matrix3TransformVector3Benchmark extends BenchmarkBase {
243+
Matrix3TransformVector3Benchmark() : super("Matrix3.transform(Vector3)");
244+
245+
final Matrix3 MX = Matrix3.rotationX(math.pi / 4);
246+
final Matrix3 MY = Matrix3.rotationY(math.pi / 4);
247+
final Matrix3 MZ = Matrix3.rotationZ(math.pi / 4);
248+
final Vector3 V1 = Vector3(10.0, 20.0, 1.0);
249+
final Vector3 V2 = Vector3(-10.0, 20.0, 1.0);
250+
final Vector3 V3 = Vector3(10.0, -20.0, 1.0);
251+
252+
static void main() {
253+
Matrix3TransformVector3Benchmark().report();
254+
}
255+
256+
@override
257+
void run() {
258+
for (int i = 0; i < 800; i++) {
259+
MX.transform(V1);
260+
MX.transform(V2);
261+
MX.transform(V3);
262+
MY.transform(V1);
263+
MY.transform(V2);
264+
MY.transform(V3);
265+
MZ.transform(V1);
266+
MZ.transform(V2);
267+
MZ.transform(V3);
268+
}
269+
}
270+
}
271+
272+
class Matrix3TransformVector2Benchmark extends BenchmarkBase {
273+
Matrix3TransformVector2Benchmark() : super("Matrix3.transform(Vector2)");
274+
275+
final Matrix3 MX = Matrix3.rotationX(math.pi / 4);
276+
final Matrix3 MY = Matrix3.rotationY(math.pi / 4);
277+
final Matrix3 MZ = Matrix3.rotationZ(math.pi / 4);
278+
final Vector2 V1 = Vector2(10.0, 20.0);
279+
final Vector2 V2 = Vector2(-10.0, 20.0);
280+
final Vector2 V3 = Vector2(10.0, -20.0);
281+
282+
static void main() {
283+
Matrix3TransformVector2Benchmark().report();
284+
}
285+
286+
@override
287+
void run() {
288+
for (int i = 0; i < 800; i++) {
289+
MX.transform2(V1);
290+
MX.transform2(V2);
291+
MX.transform2(V3);
292+
MY.transform2(V1);
293+
MY.transform2(V2);
294+
MY.transform2(V3);
295+
MZ.transform2(V1);
296+
MZ.transform2(V2);
297+
MZ.transform2(V3);
298+
}
299+
}
300+
}
301+
302+
class Matrix3TransposeMultiplyBenchmark extends BenchmarkBase {
303+
Matrix3TransposeMultiplyBenchmark() : super("Matrix3.transposeMultiply");
304+
305+
final Matrix3 MX = Matrix3.rotationX(math.pi / 4);
306+
final Matrix3 MY = Matrix3.rotationY(math.pi / 4);
307+
final Matrix3 MZ = Matrix3.rotationZ(math.pi / 4);
308+
final Matrix3 temp = Matrix3.zero();
309+
310+
static void main() {
311+
Matrix3TransposeMultiplyBenchmark().report();
312+
}
313+
314+
@override
315+
void run() {
316+
for (int i = 0; i < 100; i++) {
317+
temp.setIdentity();
318+
temp.transposeMultiply(MX);
319+
temp.transposeMultiply(MY);
320+
temp.transposeMultiply(MZ);
321+
}
322+
}
323+
}
324+
104325
void main() {
105326
MatrixMultiplyBenchmark.main();
106327
SIMDMatrixMultiplyBenchmark.main();
107328
VectorTransformBenchmark.main();
108329
SIMDVectorTransformBenchmark.main();
109330
ViewMatrixBenchmark.main();
331+
Aabb2TransformBenchmark.main();
332+
Aabb2RotateBenchmark.main();
333+
Aabb3TransformBenchmark.main();
334+
Aabb3RotateBenchmark.main();
335+
Matrix3DeterminantBenchmark.main();
336+
Matrix3TransformVector3Benchmark.main();
337+
Matrix3TransformVector2Benchmark.main();
338+
Matrix3TransposeMultiplyBenchmark.main();
110339
}

lib/src/vector_math/aabb2.dart

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,34 +76,37 @@ class Aabb2 {
7676
_max.setFrom(other._max);
7777
}
7878

79+
static Vector2 _center;
80+
static Vector2 _halfExtents;
81+
void _updateCenterAndHalfExtents() => copyCenterAndHalfExtents(
82+
_center ??= Vector2.zero(),
83+
_halfExtents ??= Vector2.zero(),
84+
);
85+
7986
/// Transform this by the transform [t].
8087
void transform(Matrix3 t) {
81-
final Vector2 center = Vector2.zero();
82-
final Vector2 halfExtents = Vector2.zero();
83-
copyCenterAndHalfExtents(center, halfExtents);
88+
_updateCenterAndHalfExtents();
8489
t
85-
..transform2(center)
86-
..absoluteRotate2(halfExtents);
90+
..transform2(_center)
91+
..absoluteRotate2(_halfExtents);
8792
_min
88-
..setFrom(center)
89-
..sub(halfExtents);
93+
..setFrom(_center)
94+
..sub(_halfExtents);
9095
_max
91-
..setFrom(center)
92-
..add(halfExtents);
96+
..setFrom(_center)
97+
..add(_halfExtents);
9398
}
9499

95100
/// Rotate this by the rotation matrix [t].
96101
void rotate(Matrix3 t) {
97-
final Vector2 center = Vector2.zero();
98-
final Vector2 halfExtents = Vector2.zero();
99-
copyCenterAndHalfExtents(center, halfExtents);
100-
t.absoluteRotate2(halfExtents);
102+
_updateCenterAndHalfExtents();
103+
t.absoluteRotate2(_halfExtents);
101104
_min
102-
..setFrom(center)
103-
..sub(halfExtents);
105+
..setFrom(_center)
106+
..sub(_halfExtents);
104107
_max
105-
..setFrom(center)
106-
..add(halfExtents);
108+
..setFrom(_center)
109+
..add(_halfExtents);
107110
}
108111

109112
/// Create a copy of this that is transformed by the transform [t] and store

lib/src/vector_math/aabb3.dart

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,34 +203,37 @@ class Aabb3 {
203203
_max.setFrom(other._max);
204204
}
205205

206+
static Vector3 _center;
207+
static Vector3 _halfExtents;
208+
void _updateCenterAndHalfExtents() => copyCenterAndHalfExtents(
209+
_center ??= Vector3.zero(),
210+
_halfExtents ??= Vector3.zero(),
211+
);
212+
206213
/// Transform this by the transform [t].
207214
void transform(Matrix4 t) {
208-
final Vector3 center = Vector3.zero();
209-
final Vector3 halfExtents = Vector3.zero();
210-
copyCenterAndHalfExtents(center, halfExtents);
215+
_updateCenterAndHalfExtents();
211216
t
212-
..transform3(center)
213-
..absoluteRotate(halfExtents);
217+
..transform3(_center)
218+
..absoluteRotate(_halfExtents);
214219
_min
215-
..setFrom(center)
216-
..sub(halfExtents);
220+
..setFrom(_center)
221+
..sub(_halfExtents);
217222
_max
218-
..setFrom(center)
219-
..add(halfExtents);
223+
..setFrom(_center)
224+
..add(_halfExtents);
220225
}
221226

222227
/// Rotate this by the rotation matrix [t].
223228
void rotate(Matrix4 t) {
224-
final Vector3 center = Vector3.zero();
225-
final Vector3 halfExtents = Vector3.zero();
226-
copyCenterAndHalfExtents(center, halfExtents);
227-
t.absoluteRotate(halfExtents);
229+
_updateCenterAndHalfExtents();
230+
t.absoluteRotate(_halfExtents);
228231
_min
229-
..setFrom(center)
230-
..sub(halfExtents);
232+
..setFrom(_center)
233+
..sub(_halfExtents);
231234
_max
232-
..setFrom(center)
233-
..add(halfExtents);
235+
..setFrom(_center)
236+
..add(_halfExtents);
234237
}
235238

236239
/// Create a copy of this that is transformed by the transform [t] and store

0 commit comments

Comments
 (0)