Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
perf(View): Improve View instantiation speed and memory consumption.
Browse files Browse the repository at this point in the history
View contains many injectors which are expensive in both speed and memory. The
New DirectiveInjector assumes that there are no more than 10 directives
per element and can be a lot more efficient than a array/hash lookup and
those it can be faster as well as smaller. This change makes View
instantiation speed 4x faster in Dartium VM.

BREAKING CHANGE:

- Injector no longer supports visibility
- The Directive:module instead of returning Module now takes
  DirectiveModule (which supports visibility)
- Application Injector and DirectiveInjector now have separate trees.
  (The root if DirectiveInjector is ApplicationInjector)
  • Loading branch information
mhevery committed Jul 17, 2014
1 parent 5ef596d commit 494deda
Show file tree
Hide file tree
Showing 79 changed files with 1,216 additions and 554 deletions.
14 changes: 8 additions & 6 deletions benchmark/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ packages:
analyzer:
description: analyzer
source: hosted
version: "0.13.6"
version: "0.15.7"
angular:
description:
path: ".."
Expand All @@ -30,23 +30,25 @@ packages:
code_transformers:
description: code_transformers
source: hosted
version: "0.1.3"
version: "0.1.4+2"
collection:
description: collection
source: hosted
version: "0.9.2"
di:
description: di
source: hosted
version: "1.0.0"
description:
path: "../../di.dart"
relative: true
source: path
version: "2.0.0-alpha.9"
html5lib:
description: html5lib
source: hosted
version: "0.10.0"
intl:
description: intl
source: hosted
version: "0.9.9"
version: "0.9.10"
logging:
description: logging
source: hosted
Expand Down
1 change: 1 addition & 0 deletions benchmark/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ transformers:
- $dart2js:
minify: false
checked: false
commandLineOptions: [--dump-info]
1 change: 1 addition & 0 deletions benchmark/web/tree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ class NgFreeTreeClass implements ShadowRootAware {

// Main function runs the benchmark.
main() {
setupModuleTypeReflector();
var cleanup, createDom;

var module = new Module()
Expand Down
4 changes: 1 addition & 3 deletions bin/parser_generator_for_spec.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:io' as io;

import 'package:di/di.dart';
import 'package:di/dynamic_injector.dart';
import 'package:angular/cache/module.dart';
import 'package:angular/core/parser/lexer.dart';
import 'package:angular/core/parser/parser.dart';
Expand All @@ -14,8 +13,7 @@ main(arguments) {
..bind(Parser, toImplementation: DynamicParser)
..install(new CacheModule());
module.bind(ParserBackend, toImplementation: DartGetterSetterGen);
Injector injector = new DynamicInjector(modules: [module],
allowImplicitInjection: true);
Injector injector = new ModuleInjector([module]);

// List generated using:
// node node_modules/karma/bin/karma run | grep -Eo ":XNAY:.*:XNAY:" | sed -e 's/:XNAY://g' | sed -e "s/^/'/" | sed -e "s/$/',/" | sort | uniq > missing_expressions
Expand Down
4 changes: 2 additions & 2 deletions lib/angular.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export 'package:angular/introspection.dart' hide
elementExpando, publishToJavaScript;
export 'package:angular/formatter/module.dart';
export 'package:angular/routing/module.dart';
export 'package:di/di.dart' hide lastKeyId;
export 'package:di/di.dart';
export 'package:di/annotations.dart';
export 'package:route_hierarchical/client.dart' hide childRoute;

1 change: 1 addition & 0 deletions lib/animate/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ import 'package:angular/core_dom/dom_util.dart' as util;
import 'package:logging/logging.dart';
import 'package:perf_api/perf_api.dart';
import 'package:di/di.dart';
import 'package:di/annotations.dart';

@MirrorsUsed(targets: const [
'angular.animate'
Expand Down
13 changes: 8 additions & 5 deletions lib/application.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import 'package:angular/routing/module.dart';
import 'package:angular/introspection.dart';

import 'package:angular/core_dom/static_keys.dart';
import 'package:angular/core_dom/directive_injector.dart';

/**
* This is the top level module which describes all Angular components,
Expand All @@ -96,6 +97,7 @@ import 'package:angular/core_dom/static_keys.dart';
*/
class AngularModule extends Module {
AngularModule() {
DirectiveInjector.initUID();
install(new CacheModule());
install(new CoreModule());
install(new CoreDomModule());
Expand All @@ -105,7 +107,6 @@ class AngularModule extends Module {
install(new PerfModule());
install(new RoutingModule());

bind(MetadataExtractor);
bind(Expando, toValue: elementExpando);
}
}
Expand Down Expand Up @@ -175,9 +176,11 @@ abstract class Application {
injector.getByKey(JS_CACHE_REGISTER_KEY);
initializeDateFormatting(null, null).then((_) {
try {
var compiler = injector.getByKey(COMPILER_KEY);
var viewFactory = compiler(rootElements, injector.getByKey(DIRECTIVE_MAP_KEY));
viewFactory(injector, rootElements);
Compiler compiler = injector.getByKey(COMPILER_KEY);
DirectiveMap directiveMap = injector.getByKey(DIRECTIVE_MAP_KEY);
RootScope rootScope = injector.getByKey(ROOT_SCOPE_KEY);
ViewFactory viewFactory = compiler(rootElements, directiveMap);
viewFactory(rootScope, injector.get(DirectiveInjector), rootElements);
} catch (e, s) {
exceptionHandler(e, s);
}
Expand All @@ -190,5 +193,5 @@ abstract class Application {
* Creates an injector function that can be used for retrieving services as well as for
* dependency injection.
*/
Injector createInjector();
Injector createInjector() => new ModuleInjector(modules);
}
3 changes: 0 additions & 3 deletions lib/application_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/
library angular.app.factory;

import 'package:di/dynamic_injector.dart';
import 'package:angular/angular.dart';
import 'package:angular/core/registry.dart';
import 'package:angular/core/parser/parser.dart' show ClosureMap;
Expand Down Expand Up @@ -64,8 +63,6 @@ class _DynamicApplication extends Application {
..bind(FieldGetterFactory, toImplementation: DynamicFieldGetterFactory)
..bind(ClosureMap, toImplementation: DynamicClosureMap);
}

Injector createInjector() => new DynamicInjector(modules: modules);
}

/**
Expand Down
26 changes: 9 additions & 17 deletions lib/application_factory_static.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
*/
library angular.app.factory.static;

import 'package:di/static_injector.dart';
import 'package:di/di.dart' show TypeFactory, Injector;
import 'package:angular/application.dart';
import 'package:angular/core/registry.dart';
import 'package:angular/core/parser/parser.dart';
Expand All @@ -46,9 +44,7 @@ export 'package:angular/change_detection/change_detection.dart' show
FieldSetter;

class _StaticApplication extends Application {
final Map<Type, TypeFactory> typeFactories;

_StaticApplication(Map<Type, TypeFactory> this.typeFactories,
_StaticApplication(
Map<Type, Object> metadata,
Map<String, FieldGetter> fieldGetters,
Map<String, FieldSetter> fieldSetters,
Expand All @@ -58,9 +54,6 @@ class _StaticApplication extends Application {
..bind(FieldGetterFactory, toValue: new StaticFieldGetterFactory(fieldGetters))
..bind(ClosureMap, toValue: new StaticClosureMap(fieldGetters, fieldSetters, symbols));
}

Injector createInjector() =>
new StaticInjector(modules: modules, typeFactories: typeFactories);
}

/**
Expand All @@ -81,20 +74,19 @@ class _StaticApplication extends Application {
* becomes:
*
* main() {
* staticApplication(generated_static_injector.factories,
* generated_static_metadata.typeAnnotations,
* generated_static_expressions.getters,
* generated_static_expressions.setters,
* generated_static_expressions.symbols)
* .addModule(new Module()..bind(HelloWorldController))
* .run();
* staticApplication(
* generated_static_metadata.typeAnnotations,
* generated_static_expressions.getters,
* generated_static_expressions.setters,
* generated_static_expressions.symbols)
* .addModule(new Module()..bind(HelloWorldController))
* .run();
*
*/
Application staticApplicationFactory(
Map<Type, TypeFactory> typeFactories,
Map<Type, Object> metadata,
Map<String, FieldGetter> fieldGetters,
Map<String, FieldSetter> fieldSetters,
Map<String, Symbol> symbols) {
return new _StaticApplication(typeFactories, metadata, fieldGetters, fieldSetters, symbols);
return new _StaticApplication(metadata, fieldGetters, fieldSetters, symbols);
}
1 change: 1 addition & 0 deletions lib/cache/js_cache_register.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ library angular.cache.js;

import 'dart:js' as js;
import 'package:di/di.dart';
import 'package:di/annotations.dart';
import 'package:angular/core/annotation_src.dart';
import 'package:angular/cache/module.dart';

Expand Down
5 changes: 4 additions & 1 deletion lib/cache/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'dart:collection';
import 'dart:async';

import 'package:di/di.dart';
import 'package:angular/core/annotation_src.dart';
import 'package:di/annotations.dart';

part "cache.dart";
part "cache_register.dart";
Expand All @@ -13,4 +13,7 @@ class CacheModule extends Module {
CacheModule() {
bind(CacheRegister);
}
CacheModule.withReflector(reflector): super.withReflector(reflector) {
bind(CacheRegister);
}
}
1 change: 1 addition & 0 deletions lib/change_detection/ast_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ library angular.change_detection.ast_parser;

import 'dart:collection';

import 'package:di/annotations.dart';
import 'package:angular/core/parser/syntax.dart' as syntax;
import 'package:angular/core/parser/parser.dart';
import 'package:angular/core/formatter.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/core/annotation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ export "package:angular/core/annotation_src.dart" show
Formatter,
DirectiveBinder,
DirectiveBinderFn,
Injectable,

Directive,
Component,
Controller,
Decorator,
Visibility,

DirectiveAnnotation,
NgAttr,
Expand Down
Loading

0 comments on commit 494deda

Please sign in to comment.