| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:math' as math; |
| |
| import 'package:flutter/rendering.dart'; |
| |
| import '../common.dart'; |
| |
| const int _kNumIterations = 10000000; |
| const int _kNumWarmUp = 100000; |
| |
| void main() { |
| assert(false, "Don't run benchmarks in debug mode! Use 'flutter run --release'."); |
| print('MatrixUtils.transformRect and .transformPoint benchmark...'); |
| |
| Matrix4 makePerspective(double radius, double angle, double perspective) { |
| return MatrixUtils.createCylindricalProjectionTransform( |
| radius: radius, |
| angle: angle, |
| perspective: perspective, |
| ); |
| } |
| |
| final List<Matrix4> affineTransforms = <Matrix4>[ |
| Matrix4.identity()..scale(1.2, 1.3, 1.0)..rotateZ(0.1), |
| Matrix4.identity()..translate(12.0, 13.0, 10.0), |
| Matrix4.identity()..scale(1.2, 1.3, 1.0)..translate(12.0, 13.0, 10.0), |
| ]; |
| final List<Matrix4> perspectiveTransforms = <Matrix4>[ |
| makePerspective(10.0, math.pi / 8.0, 0.3), |
| makePerspective( 8.0, math.pi / 8.0, 0.2), |
| makePerspective( 1.0, math.pi / 4.0, 0.1)..rotateX(0.1), |
| ]; |
| final List<Rect> rectangles = <Rect>[ |
| const Rect.fromLTRB(1.1, 1.2, 1.5, 1.8), |
| const Rect.fromLTRB(1.1, 1.2, 0.0, 1.0), |
| const Rect.fromLTRB(1.1, 1.2, 1.3, 1.0), |
| const Rect.fromLTRB(-1.1, -1.2, 0.0, 1.0), |
| const Rect.fromLTRB(-1.1, -1.2, -1.5, -1.8), |
| ]; |
| final List<Offset> offsets = <Offset>[ |
| const Offset(1.1, 1.2), |
| const Offset(1.5, 1.8), |
| Offset.zero, |
| const Offset(-1.1, -1.2), |
| const Offset(-1.5, -1.8), |
| ]; |
| final int nAffine = affineTransforms.length; |
| final int nPerspective = perspectiveTransforms.length; |
| final int nRectangles = rectangles.length; |
| final int nOffsets = offsets.length; |
| |
| // Warm up lap |
| for (int i = 0; i < _kNumWarmUp; i += 1) { |
| final Matrix4 transform = perspectiveTransforms[i % nPerspective]; |
| final Rect rect = rectangles[(i ~/ nPerspective) % nRectangles]; |
| final Offset offset = offsets[(i ~/ nPerspective) % nOffsets]; |
| MatrixUtils.transformRect(transform, rect); |
| MatrixUtils.transformPoint(transform, offset); |
| } |
| for (int i = 0; i < _kNumWarmUp; i += 1) { |
| final Matrix4 transform = affineTransforms[i % nAffine]; |
| final Rect rect = rectangles[(i ~/ nAffine) % nRectangles]; |
| final Offset offset = offsets[(i ~/ nAffine) % nOffsets]; |
| MatrixUtils.transformRect(transform, rect); |
| MatrixUtils.transformPoint(transform, offset); |
| } |
| |
| final Stopwatch watch = Stopwatch(); |
| watch.start(); |
| for (int i = 0; i < _kNumIterations; i += 1) { |
| final Matrix4 transform = perspectiveTransforms[i % nPerspective]; |
| final Rect rect = rectangles[(i ~/ nPerspective) % nRectangles]; |
| MatrixUtils.transformRect(transform, rect); |
| } |
| watch.stop(); |
| final int rectMicrosecondsPerspective = watch.elapsedMicroseconds; |
| |
| watch.reset(); |
| watch.start(); |
| for (int i = 0; i < _kNumIterations; i += 1) { |
| final Matrix4 transform = affineTransforms[i % nAffine]; |
| final Rect rect = rectangles[(i ~/ nAffine) % nRectangles]; |
| MatrixUtils.transformRect(transform, rect); |
| } |
| watch.stop(); |
| final int rectMicrosecondsAffine = watch.elapsedMicroseconds; |
| |
| watch.reset(); |
| watch.start(); |
| for (int i = 0; i < _kNumIterations; i += 1) { |
| final Matrix4 transform = perspectiveTransforms[i % nPerspective]; |
| final Offset offset = offsets[(i ~/ nPerspective) % nOffsets]; |
| MatrixUtils.transformPoint(transform, offset); |
| } |
| watch.stop(); |
| final int pointMicrosecondsPerspective = watch.elapsedMicroseconds; |
| |
| watch.reset(); |
| watch.start(); |
| for (int i = 0; i < _kNumIterations; i += 1) { |
| final Matrix4 transform = affineTransforms[i % nAffine]; |
| final Offset offset = offsets[(i ~/ nAffine) % nOffsets]; |
| MatrixUtils.transformPoint(transform, offset); |
| } |
| watch.stop(); |
| final int pointMicrosecondsAffine = watch.elapsedMicroseconds; |
| |
| final BenchmarkResultPrinter printer = BenchmarkResultPrinter(); |
| const double scale = 1000.0 / _kNumIterations; |
| printer.addResult( |
| description: 'MatrixUtils.transformRectPerspective', |
| value: rectMicrosecondsPerspective * scale, |
| unit: 'ns per iteration', |
| name: 'MatrixUtils_persp_transformRect_iteration', |
| ); |
| printer.addResult( |
| description: 'MatrixUtils.transformRectAffine', |
| value: rectMicrosecondsAffine * scale, |
| unit: 'ns per iteration', |
| name: 'MatrixUtils_affine_transformRect_iteration', |
| ); |
| printer.addResult( |
| description: 'MatrixUtils.transformPointPerspective', |
| value: pointMicrosecondsPerspective * scale, |
| unit: 'ns per iteration', |
| name: 'MatrixUtils_persp_transformPoint_iteration', |
| ); |
| printer.addResult( |
| description: 'MatrixUtils.transformPointAffine', |
| value: pointMicrosecondsAffine * scale, |
| unit: 'ns per iteration', |
| name: 'MatrixUtils_affine_transformPoint_iteration', |
| ); |
| printer.printToStdout(); |
| } |