| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| // |
| // This benchmark suite measures the overhead of dynamically calling functions |
| // and closures by calling a set of functions and closures, testing non-dynamic |
| // calls, calls after casting the function tearoff or closure to dynamic, and |
| // similarly defined functions and closures except that the parameters and |
| // return types are all dynamic. |
| |
| // @dart=2.9 |
| |
| import 'package:benchmark_harness/benchmark_harness.dart'; |
| |
| const int kRepeat = 100; |
| |
| void main() { |
| const NonDynamicFunction().report(); |
| const NonDynamicFunctionOptSkipped().report(); |
| const NonDynamicFunctionOptProvided().report(); |
| const NonDynamicFunctionNamedSkipped().report(); |
| const NonDynamicFunctionNamedProvided().report(); |
| const NonDynamicClosure().report(); |
| const NonDynamicClosureOptSkipped().report(); |
| const NonDynamicClosureOptProvided().report(); |
| const NonDynamicClosureNamedSkipped().report(); |
| const NonDynamicClosureNamedProvided().report(); |
| const DynamicCastFunction().report(); |
| const DynamicCastFunctionOptSkipped().report(); |
| const DynamicCastFunctionOptProvided().report(); |
| const DynamicCastFunctionNamedSkipped().report(); |
| const DynamicCastFunctionNamedProvided().report(); |
| const DynamicCastClosure().report(); |
| const DynamicCastClosureOptSkipped().report(); |
| const DynamicCastClosureOptProvided().report(); |
| const DynamicCastClosureNamedSkipped().report(); |
| const DynamicCastClosureNamedProvided().report(); |
| const DynamicDefFunction().report(); |
| const DynamicDefFunctionOptSkipped().report(); |
| const DynamicDefFunctionOptProvided().report(); |
| const DynamicDefFunctionNamedSkipped().report(); |
| const DynamicDefFunctionNamedProvided().report(); |
| const DynamicDefClosure().report(); |
| const DynamicDefClosureOptSkipped().report(); |
| const DynamicDefClosureOptProvided().report(); |
| const DynamicDefClosureNamedSkipped().report(); |
| const DynamicDefClosureNamedProvided().report(); |
| const DynamicClassASingleton().report(); |
| const DynamicClassBSingleton().report(); |
| const DynamicClassCFresh().report(); |
| const DynamicClassDFresh().report(); |
| } |
| |
| @pragma('vm:never-inline') |
| void f1(String s) {} |
| @pragma('vm:never-inline') |
| Function(String) c1 = (String s) => {}; |
| @pragma('vm:never-inline') |
| void f2(String s, [String t = 'default']) {} |
| @pragma('vm:never-inline') |
| Function(String, [String]) c2 = (String s, [String t = 'default']) => {}; |
| @pragma('vm:never-inline') |
| void f3(String s, {String t = 'default'}) {} |
| @pragma('vm:never-inline') |
| Function(String, {String t}) c3 = (String s, {String t = 'default'}) => {}; |
| @pragma('vm:never-inline') |
| dynamic df1 = f1 as dynamic; |
| @pragma('vm:never-inline') |
| dynamic dc1 = c1 as dynamic; |
| @pragma('vm:never-inline') |
| dynamic df2 = f2 as dynamic; |
| @pragma('vm:never-inline') |
| dynamic dc2 = c2 as dynamic; |
| @pragma('vm:never-inline') |
| dynamic df3 = f3 as dynamic; |
| @pragma('vm:never-inline') |
| dynamic dc3 = c3 as dynamic; |
| @pragma('vm:never-inline') |
| dynamic df1NonCast(dynamic s) {} |
| @pragma('vm:never-inline') |
| Function dc1NonCast = (dynamic s) => {}; |
| @pragma('vm:never-inline') |
| dynamic df2NonCast(dynamic s, [dynamic t = 'default']) {} |
| @pragma('vm:never-inline') |
| Function dc2NonCast = (dynamic s, [dynamic t = 'default']) => {}; |
| @pragma('vm:never-inline') |
| dynamic df3NonCast(dynamic s, {dynamic t = 'default'}) {} |
| @pragma('vm:never-inline') |
| Function dc3NonCast = (dynamic s, {dynamic t = 'default'}) => {}; |
| |
| class A { |
| const A(); |
| } |
| |
| class B extends A { |
| const B(); |
| } |
| |
| @pragma('vm:never-inline') |
| dynamic k = (A a) {}; |
| |
| class C { |
| C(); |
| } |
| |
| class D extends C { |
| D(); |
| } |
| |
| @pragma('vm:never-inline') |
| dynamic j = (C c) {}; |
| |
| class NonDynamicFunction extends BenchmarkBase { |
| const NonDynamicFunction() : super('Dynamic.NonDynamicFunction'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| f1(''); |
| } |
| } |
| } |
| |
| class NonDynamicClosure extends BenchmarkBase { |
| const NonDynamicClosure() : super('Dynamic.NonDynamicClosure'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| c1(''); |
| } |
| } |
| } |
| |
| class NonDynamicFunctionOptSkipped extends BenchmarkBase { |
| const NonDynamicFunctionOptSkipped() |
| : super('Dynamic.NonDynamicFunctionOptSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| f2(''); |
| } |
| } |
| } |
| |
| class NonDynamicFunctionOptProvided extends BenchmarkBase { |
| const NonDynamicFunctionOptProvided() |
| : super('Dynamic.NonDynamicFunctionOptProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| f2('', ''); |
| } |
| } |
| } |
| |
| class NonDynamicFunctionNamedSkipped extends BenchmarkBase { |
| const NonDynamicFunctionNamedSkipped() |
| : super('Dynamic.NonDynamicFunctionNamedSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| f3(''); |
| } |
| } |
| } |
| |
| class NonDynamicFunctionNamedProvided extends BenchmarkBase { |
| const NonDynamicFunctionNamedProvided() |
| : super('Dynamic.NonDynamicFunctionNamedProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| f3('', t: ''); |
| } |
| } |
| } |
| |
| class NonDynamicClosureOptSkipped extends BenchmarkBase { |
| const NonDynamicClosureOptSkipped() |
| : super('Dynamic.NonDynamicClosureOptSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| c2(''); |
| } |
| } |
| } |
| |
| class NonDynamicClosureOptProvided extends BenchmarkBase { |
| const NonDynamicClosureOptProvided() |
| : super('Dynamic.NonDynamicClosureOptProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| c2('', ''); |
| } |
| } |
| } |
| |
| class NonDynamicClosureNamedSkipped extends BenchmarkBase { |
| const NonDynamicClosureNamedSkipped() |
| : super('Dynamic.NonDynamicClosureNamedSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| c3(''); |
| } |
| } |
| } |
| |
| class NonDynamicClosureNamedProvided extends BenchmarkBase { |
| const NonDynamicClosureNamedProvided() |
| : super('Dynamic.NonDynamicClosureNamedProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| c3('', t: ''); |
| } |
| } |
| } |
| |
| class DynamicCastFunction extends BenchmarkBase { |
| const DynamicCastFunction() : super('Dynamic.DynamicCastFunction'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df1(''); |
| } |
| } |
| } |
| |
| class DynamicCastClosure extends BenchmarkBase { |
| const DynamicCastClosure() : super('Dynamic.DynamicCastClosure'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc1(''); |
| } |
| } |
| } |
| |
| class DynamicCastFunctionOptSkipped extends BenchmarkBase { |
| const DynamicCastFunctionOptSkipped() |
| : super('Dynamic.DynamicCastFunctionOptSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df2(''); |
| } |
| } |
| } |
| |
| class DynamicCastFunctionOptProvided extends BenchmarkBase { |
| const DynamicCastFunctionOptProvided() |
| : super('Dynamic.DynamicCastFunctionOptProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df2('', ''); |
| } |
| } |
| } |
| |
| class DynamicCastFunctionNamedSkipped extends BenchmarkBase { |
| const DynamicCastFunctionNamedSkipped() |
| : super('Dynamic.DynamicCastFunctionNamedSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df3(''); |
| } |
| } |
| } |
| |
| class DynamicCastFunctionNamedProvided extends BenchmarkBase { |
| const DynamicCastFunctionNamedProvided() |
| : super('Dynamic.DynamicCastFunctionNamedProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df3('', t: ''); |
| } |
| } |
| } |
| |
| class DynamicCastClosureOptSkipped extends BenchmarkBase { |
| const DynamicCastClosureOptSkipped() |
| : super('Dynamic.DynamicCastClosureOptSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc2(''); |
| } |
| } |
| } |
| |
| class DynamicCastClosureOptProvided extends BenchmarkBase { |
| const DynamicCastClosureOptProvided() |
| : super('Dynamic.DynamicCastClosureOptProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc2('', ''); |
| } |
| } |
| } |
| |
| class DynamicCastClosureNamedSkipped extends BenchmarkBase { |
| const DynamicCastClosureNamedSkipped() |
| : super('Dynamic.DynamicCastClosureNamedSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc3(''); |
| } |
| } |
| } |
| |
| class DynamicCastClosureNamedProvided extends BenchmarkBase { |
| const DynamicCastClosureNamedProvided() |
| : super('Dynamic.DynamicCastClosureNamedProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc3('', t: ''); |
| } |
| } |
| } |
| |
| class DynamicDefFunction extends BenchmarkBase { |
| const DynamicDefFunction() : super('Dynamic.DynamicDefFunction'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df1NonCast(''); |
| } |
| } |
| } |
| |
| class DynamicDefClosure extends BenchmarkBase { |
| const DynamicDefClosure() : super('Dynamic.DynamicDefClosure'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc1NonCast(''); |
| } |
| } |
| } |
| |
| class DynamicDefFunctionOptSkipped extends BenchmarkBase { |
| const DynamicDefFunctionOptSkipped() |
| : super('Dynamic.DynamicDefFunctionOptSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df2NonCast(''); |
| } |
| } |
| } |
| |
| class DynamicDefFunctionOptProvided extends BenchmarkBase { |
| const DynamicDefFunctionOptProvided() |
| : super('Dynamic.DynamicDefFunctionOptProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df2NonCast('', ''); |
| } |
| } |
| } |
| |
| class DynamicDefFunctionNamedSkipped extends BenchmarkBase { |
| const DynamicDefFunctionNamedSkipped() |
| : super('Dynamic.DynamicDefFunctionNamedSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df3NonCast(''); |
| } |
| } |
| } |
| |
| class DynamicDefFunctionNamedProvided extends BenchmarkBase { |
| const DynamicDefFunctionNamedProvided() |
| : super('Dynamic.DynamicDefFunctionNamedProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| df3NonCast('', t: ''); |
| } |
| } |
| } |
| |
| class DynamicDefClosureOptSkipped extends BenchmarkBase { |
| const DynamicDefClosureOptSkipped() |
| : super('Dynamic.DynamicDefClosureOptSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc2NonCast(''); |
| } |
| } |
| } |
| |
| class DynamicDefClosureOptProvided extends BenchmarkBase { |
| const DynamicDefClosureOptProvided() |
| : super('Dynamic.DynamicDefClosureOptProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc2NonCast('', ''); |
| } |
| } |
| } |
| |
| class DynamicDefClosureNamedSkipped extends BenchmarkBase { |
| const DynamicDefClosureNamedSkipped() |
| : super('Dynamic.DynamicDefClosureNamedSkipped'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc3NonCast(''); |
| } |
| } |
| } |
| |
| class DynamicDefClosureNamedProvided extends BenchmarkBase { |
| const DynamicDefClosureNamedProvided() |
| : super('Dynamic.DynamicDefClosureNamedProvided'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| dc3NonCast('', t: ''); |
| } |
| } |
| } |
| |
| class DynamicClassASingleton extends BenchmarkBase { |
| final A a; |
| const DynamicClassASingleton() |
| : a = const A(), |
| super('Dynamic.DynamicClassASingleton'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| k(a); |
| } |
| } |
| } |
| |
| class DynamicClassBSingleton extends BenchmarkBase { |
| final B b; |
| const DynamicClassBSingleton() |
| : b = const B(), |
| super('Dynamic.DynamicClassBSingleton'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| k(b); |
| } |
| } |
| } |
| |
| class DynamicClassCFresh extends BenchmarkBase { |
| const DynamicClassCFresh() : super('Dynamic.DynamicClassCFresh'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| j(C()); |
| } |
| } |
| } |
| |
| class DynamicClassDFresh extends BenchmarkBase { |
| const DynamicClassDFresh() : super('Dynamic.DynamicClassDFresh'); |
| |
| @override |
| void run() { |
| for (int i = 0; i < kRepeat; i++) { |
| j(D()); |
| } |
| } |
| } |