From 1864f60afb3cb67cb4dbef406b9376cbfe966401 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Thu, 19 Mar 2015 15:47:10 -0700 Subject: [PATCH] feat(benchmarks): Add basic dart transformer benchmarks. Adds simple benchmarks for various transformation phases, as well as hello_world. Does not integrate these into any benchmark frameworks yet. --- modules/angular2/pubspec.yaml | 2 +- .../benchmark.transform.server.spec.dart | 24 ++++++ .../transform/bind_generator/simple.dart | 45 ++++++++++ .../transform/directive_linker/simple.dart | 80 ++++++++++++++++++ .../transform/directive_processor/simple.dart | 35 ++++++++ .../transform/integration/hello_world.dart | 84 +++++++++++++++++++ .../transform/reflection_remover/simple.dart | 36 ++++++++ .../transform/template_compiler/inline.dart | 48 +++++++++++ .../transform/template_compiler/url.dart | 55 ++++++++++++ 9 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 modules/angular2/test/benchmark/transform/benchmark.transform.server.spec.dart create mode 100644 modules/angular2/test/benchmark/transform/bind_generator/simple.dart create mode 100644 modules/angular2/test/benchmark/transform/directive_linker/simple.dart create mode 100644 modules/angular2/test/benchmark/transform/directive_processor/simple.dart create mode 100644 modules/angular2/test/benchmark/transform/integration/hello_world.dart create mode 100644 modules/angular2/test/benchmark/transform/reflection_remover/simple.dart create mode 100644 modules/angular2/test/benchmark/transform/template_compiler/inline.dart create mode 100644 modules/angular2/test/benchmark/transform/template_compiler/url.dart diff --git a/modules/angular2/pubspec.yaml b/modules/angular2/pubspec.yaml index b7114930ca..4249198564 100644 --- a/modules/angular2/pubspec.yaml +++ b/modules/angular2/pubspec.yaml @@ -11,7 +11,7 @@ environment: dependencies: analyzer: '^0.24.4' barback: '^0.15.2+2' - code_transformers: '^0.2.5' + code_transformers: '^0.2.8' dart_style: '^0.1.3' html: '^0.12.0' logging: '>=0.9.0 <0.11.0' diff --git a/modules/angular2/test/benchmark/transform/benchmark.transform.server.spec.dart b/modules/angular2/test/benchmark/transform/benchmark.transform.server.spec.dart new file mode 100644 index 0000000000..736bffd6b3 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/benchmark.transform.server.spec.dart @@ -0,0 +1,24 @@ +library angular2.test.benchmark.transform; + +import 'package:guinness/guinness.dart'; +import 'package:unittest/vm_config.dart'; + +import 'bind_generator/simple.dart' as bindGenerator; +import 'directive_linker/simple.dart' as directiveLinker; +import 'directive_processor/simple.dart' as directiveProcessor; +import 'integration/hello_world.dart' as helloWorld; +import 'reflection_remover/simple.dart' as reflectionRemover; +import 'template_compiler/inline.dart' as inlineTemplateCompiler; +import 'template_compiler/url.dart' as urlTemplateCompiler; + +main() { + useVMConfiguration(); + describe('Bind Generator Benchmark', bindGenerator.allTests); + describe('Directive Linker Benchmark', directiveLinker.allTests); + describe('Directive Processor Benchmark', directiveProcessor.allTests); + describe('Hello World Transformer Benchmark', helloWorld.allTests); + describe('Reflection Remover Benchmark', reflectionRemover.allTests); + describe('Inline Template Compiler Benchmark', + inlineTemplateCompiler.allTests); + describe('Url Template Compiler Benchmark', urlTemplateCompiler.allTests); +} diff --git a/modules/angular2/test/benchmark/transform/bind_generator/simple.dart b/modules/angular2/test/benchmark/transform/bind_generator/simple.dart new file mode 100644 index 0000000000..81c9f26e42 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/bind_generator/simple.dart @@ -0,0 +1,45 @@ +library angular2.benchmark.transform.bind_generator.simple; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/bind_generator/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Bind Generator Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var options = new TransformerOptions(['this_is_ignored.dart']); + var files = {new AssetId('a', 'a.ng_deps.dart'): aContents}; + var benchmark = + new TransformerBenchmark([[new BindGenerator(options)]], files); + print('\nRunning bind_generator benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const aContents = ''' +library bar.ng_deps.dart; + +import 'bar.dart'; +import 'package:angular2/src/core/annotations/annotations.dart'; + +bool _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; + reflector + ..registerType(ToolTip, { + 'factory': () => new ToolTip(), + 'parameters': const [], + 'annotations': const [ + const Decorator( + selector: '[tool-tip]', bind: const {'text': 'tool-tip'}) + ] + }); +}'''; diff --git a/modules/angular2/test/benchmark/transform/directive_linker/simple.dart b/modules/angular2/test/benchmark/transform/directive_linker/simple.dart new file mode 100644 index 0000000000..ab4c7f41d3 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/directive_linker/simple.dart @@ -0,0 +1,80 @@ +library angular2.benchmark.transform.directive_linker.simple; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/directive_linker/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Directive Linker Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var files = { + new AssetId('a', 'a.ng_deps.dart'): aContents, + new AssetId('a', 'b.ng_deps.dart'): bContents, + new AssetId('a', 'c.ng_deps.dart'): cContents, + }; + var benchmark = new TransformerBenchmark([[new DirectiveLinker()]], files); + print('\nRunning directive_linker benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const aContents = ''' +library a.ng_deps.dart; + +import 'package:angular2/src/core/application.dart'; +import 'package:angular2/src/reflection/reflection_capabilities.dart'; +import 'b.dart'; + +bool _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; +}'''; + +const bContents = ''' +library b.ng_deps.dart; + +import 'b.dart'; +import 'package:angular2/src/core/annotations/annotations.dart'; + +bool _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; + reflector + ..registerType(DependencyComponent, { + 'factory': () => new DependencyComponent(), + 'parameters': const [], + 'annotations': const [const Component(selector: '[salad]')] + }); +} +'''; + +const cContents = ''' +library c.ng_deps.dart; + +import 'c.dart'; +import 'package:angular2/src/core/annotations/annotations.dart'; +import 'b.dart' as dep; + +bool _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; + reflector + ..registerType(MyComponent, { + 'factory': () => new MyComponent(), + 'parameters': const [], + 'annotations': const [ + const Component( + selector: '[soup]', services: const [dep.DependencyComponent]) + ] + }); +}'''; diff --git a/modules/angular2/test/benchmark/transform/directive_processor/simple.dart b/modules/angular2/test/benchmark/transform/directive_processor/simple.dart new file mode 100644 index 0000000000..28ddaa9ed9 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/directive_processor/simple.dart @@ -0,0 +1,35 @@ +library angular2.benchmark.transform.directive_processor.simple; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/directive_processor/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Directive Processor Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var options = new TransformerOptions(['this_is_ignored.dart']); + var files = {new AssetId('a', 'a.dart'): aContents,}; + var benchmark = + new TransformerBenchmark([[new DirectiveProcessor(options)]], files); + print('\nRunning directive_processor benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const aContents = ''' +library dinner.soup; + +import 'package:angular2/src/core/annotations/annotations.dart'; + +@Component(selector: '[soup]') +class SoupComponent { + SoupComponent(@Tasty String description, @Inject(Salt) salt); +} +'''; diff --git a/modules/angular2/test/benchmark/transform/integration/hello_world.dart b/modules/angular2/test/benchmark/transform/integration/hello_world.dart new file mode 100644 index 0000000000..60aeb5bb86 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/integration/hello_world.dart @@ -0,0 +1,84 @@ +library angular2.benchmark.transform.integration.hello_world; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Hello World Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var options = new TransformerOptions(['index.dart']); + var files = { + new AssetId('a', 'web/index.dart'): indexContents, + new AssetId('a', 'web/index_common.dart'): indexCommonContents, + }; + var benchmark = new TransformerBenchmark( + new AngularTransformerGroup(options).phases, files); + print('\nRunning hello_world benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const indexContents = ''' +library examples.src.hello_world.index; + +import "index_common.dart" as app; +import "package:angular2/src/reflection/reflection.dart" show reflector; +import "package:angular2/src/reflection/reflection_capabilities.dart" + show ReflectionCapabilities; + +main() { + reflector.reflectionCapabilities = new ReflectionCapabilities(); + app.main(); +} +'''; + +const indexCommonContents = ''' +library examples.src.hello_world.index_common; + +import "package:angular2/angular2.dart" + show bootstrap, Component, Decorator, Template, NgElement; +import "package:angular2/di.dart" show Injectable; + +@Component(selector: "hello-app", services: const [GreetingService]) +@Template( + inline: '
{{greeting}} world!
' + '', + directives: const [RedDec]) +class HelloCmp { + String greeting; + HelloCmp(GreetingService service) { + this.greeting = service.greeting; + } + changeGreeting() { + this.greeting = "howdy"; + } +} + +@Decorator(selector: "[red]") +class RedDec { + RedDec(NgElement el) { + el.domElement.style.color = "red"; + } +} + +@Injectable() +class GreetingService { + String greeting; + GreetingService() { + this.greeting = "hello"; + } +} + +main() { + bootstrap(HelloCmp); +} +'''; diff --git a/modules/angular2/test/benchmark/transform/reflection_remover/simple.dart b/modules/angular2/test/benchmark/transform/reflection_remover/simple.dart new file mode 100644 index 0000000000..2e08fc90e6 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/reflection_remover/simple.dart @@ -0,0 +1,36 @@ +library angular2.benchmark.transform.reflection_remover.simple; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/reflection_remover/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Reflection Remover Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var options = new TransformerOptions(['web/index.dart']); + var files = {new AssetId('a', 'web/index.dart'): indexContents,}; + var benchmark = + new TransformerBenchmark([[new ReflectionRemover(options)]], files); + print('\nRunning reflection_remover benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const indexContents = ''' +library web_foo; + +import 'package:angular2/src/core/application.dart'; +import 'package:angular2/src/reflection/reflection.dart'; +import 'package:angular2/src/reflection/reflection_capabilities.dart'; + +void main() { + reflector.reflectionCapabilities = new ReflectionCapabilities(); + bootstrap(MyComponent); +}'''; diff --git a/modules/angular2/test/benchmark/transform/template_compiler/inline.dart b/modules/angular2/test/benchmark/transform/template_compiler/inline.dart new file mode 100644 index 0000000000..e92fcaa5d2 --- /dev/null +++ b/modules/angular2/test/benchmark/transform/template_compiler/inline.dart @@ -0,0 +1,48 @@ +library angular2.benchmark.transform.template_compiler.inline; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/template_compiler/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Inline Template Compiler Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var options = new TransformerOptions(['index.dart']); + var files = {new AssetId('a', 'web/a.ng_deps.dart'): aContents,}; + var benchmark = + new TransformerBenchmark([[new TemplateCompiler(options)]], files); + print('\nRunning template_compiler inline benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const aContents = ''' +library examples.src.hello_world.index_common_dart; + +import 'hello.dart'; +import 'package:angular2/angular2.dart' + show bootstrap, Component, Decorator, Template, NgElement; + +bool _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; + reflector + ..registerType(HelloCmp, { + 'factory': () => new HelloCmp(), + 'parameters': const [const []], + 'annotations': const [ + const Component(selector: 'hello-app'), + const Template( + inline: '{{greeting}}') + ] + }); +} +'''; diff --git a/modules/angular2/test/benchmark/transform/template_compiler/url.dart b/modules/angular2/test/benchmark/transform/template_compiler/url.dart new file mode 100644 index 0000000000..a667d688ea --- /dev/null +++ b/modules/angular2/test/benchmark/transform/template_compiler/url.dart @@ -0,0 +1,55 @@ +library angular2.benchmark.transform.template_compiler.url; + +import 'dart:async'; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/template_compiler/transformer.dart'; +import 'package:barback/barback.dart'; +import 'package:code_transformers/benchmarks.dart'; +import 'package:unittest/unittest.dart'; + +Future main() => runBenchmark(); + +allTests() { + test('Url Template Compiler Benchmark Runs', runBenchmark); +} + +Future runBenchmark() async { + var options = new TransformerOptions(['index.dart']); + var files = { + new AssetId('a', 'web/a.ng_deps.dart'): aContents, + new AssetId('a', 'web/template.html'): templateContents, + }; + var benchmark = + new TransformerBenchmark([[new TemplateCompiler(options)]], files); + print('\nRunning template_compiler url benchmark...'); + var result = await benchmark.measure(); + print('Done, took ${result.round()}μs on average.'); +} + +const aContents = ''' +library examples.src.hello_world.index_common_dart; + +import 'hello.dart'; +import 'package:angular2/angular2.dart' + show bootstrap, Component, Decorator, Template, NgElement; + +bool _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; + reflector + ..registerType(HelloCmp, { + 'factory': () => new HelloCmp(), + 'parameters': const [const []], + 'annotations': const [ + const Component(selector: 'hello-app'), + const Template(url: 'template.html') + ] + }); +} +'''; + +const templateContents = ''' + +{{greeting}} +''';