| // 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. | |
| 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') | |
| @pragma('wasm:never-inline') | |
| void f1(String s) {} | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| Function(String) c1 = (String s) => {}; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| void f2(String s, [String t = 'default']) {} | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| Function(String, [String]) c2 = (String s, [String t = 'default']) => {}; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| void f3(String s, {String t = 'default'}) {} | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| Function(String, {String t}) c3 = (String s, {String t = 'default'}) => {}; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic df1 = f1 as dynamic; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic dc1 = c1 as dynamic; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic df2 = f2 as dynamic; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic dc2 = c2 as dynamic; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic df3 = f3 as dynamic; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic dc3 = c3 as dynamic; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic df1NonCast(dynamic s) {} | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| Function dc1NonCast = (dynamic s) => {}; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic df2NonCast(dynamic s, [dynamic t = 'default']) {} | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| Function dc2NonCast = (dynamic s, [dynamic t = 'default']) => {}; | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic df3NonCast(dynamic s, {dynamic t = 'default'}) {} | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| Function dc3NonCast = (dynamic s, {dynamic t = 'default'}) => {}; | |
| class A { | |
| const A(); | |
| } | |
| class B extends A { | |
| const B(); | |
| } | |
| @pragma('vm:never-inline') | |
| @pragma('wasm:never-inline') | |
| dynamic k = (A a) {}; | |
| class C { | |
| C(); | |
| } | |
| class D extends C { | |
| D(); | |
| } | |
| @pragma('vm:never-inline') | |
| @pragma('wasm: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()); | |
| } | |
| } | |
| } |