Skip to content
This repository has been archived by the owner on Dec 6, 2017. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
perf(injector): inlined getProviderWithInjector
  • Loading branch information
Anting Shen authored and IgorMinar committed Jun 11, 2014
1 parent 344405d commit d2a38b5
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 49 deletions.
3 changes: 1 addition & 2 deletions benchmark/injector_benchmark_common.dart
Expand Up @@ -30,8 +30,7 @@ class InjectorBenchmark extends BenchmarkBase {
..type(D)
..type(E)
..type(E, withAnnotation: AnnTwo, implementedBy: ETwo )
..type(F)
..type(G);
..type(F);
}

teardown() {
Expand Down
11 changes: 10 additions & 1 deletion benchmark/instance_benchmark.dart
Expand Up @@ -6,8 +6,17 @@ import 'injector_benchmark_common.dart';
class InstanceBenchmark extends InjectorBenchmark{
InstanceBenchmark(name, injectorFactory) : super(name, injectorFactory);

StaticInjector injector;

void setup(){
super.setup();
injector = injectorFactory([module]);
for (var i = 0; i < 20; i++) {
injector = injector.createChild(null);
}
}

void run(){
Injector injector = injectorFactory([module]);
for (var i = 0; i < 30; i++) {
injector.get(A);
}
Expand Down
84 changes: 38 additions & 46 deletions lib/src/base_injector.dart
Expand Up @@ -95,9 +95,23 @@ abstract class BaseInjector implements Injector, ObjectFactory {
error(resolving, 'Cannot resolve a circular dependency!', key));
}

var providerWithInjector = _getProviderWithInjectorForKey(key, resolving);
var provider = providerWithInjector.provider;
var injector = providerWithInjector.injector;
// This code is pasted in createChildWithResolvingHistory for performance
var provider = key.id < _providers.length ? _providers[key.id] : null;
var injector = this;
while (provider == null){
if (injector.parent == null){
if (allowImplicitInjection) {
provider = new TypeProvider(key.type);
break;
}
throw new NoProviderError(
error(resolving, 'No provider found for ${key}!', key));
}
injector = injector.parent;
provider = key.id < injector._providers.length ?
injector._providers[key.id] : null;
}

var visible = provider.visibility == null ||
provider.visibility(requester, injector);

Expand All @@ -116,8 +130,7 @@ abstract class BaseInjector implements Injector, ObjectFactory {
throw new NoProviderError(
error(resolving, 'No provider found for ${key}!', key));
}
injector = injector.parent
._getProviderWithInjectorForKey(key, resolving).injector;
injector = injector.parent;
}
return injector.getInstanceByKey(key, requester, resolving);
}
Expand All @@ -127,43 +140,13 @@ abstract class BaseInjector implements Injector, ObjectFactory {

// cache the value.
if (allowImplicitInjection == true) {
providerWithInjector.injector._instancesMap[key.id] = value;
injector._instancesMap[key.id] = value;
} else {
providerWithInjector.injector._instancesList[key.id] = value;
injector._instancesList[key.id] = value;
}
return value;
}

/**
* Finds the nearest ancestor injector that binds a [Provider] to [key] and
* returns that [Provider] and its binding [Injector]. If there is no such
* [Injector], then
*
* - if [allowImplicitInjection] is true for the root injector (not this
* injector), returns a default [Provider] and the root injector.
* - if [allowImplicitInjector] is false for the root injector, throws
* [NoProviderError].
*
* [resolving] is only used for error reporting.
*/
_ProviderWithInjector _getProviderWithInjectorForKey(
Key key, ResolutionContext resolving) {
if (key.id < _providers.length) {
var provider = _providers[key.id];
if (provider != null) {
return new _ProviderWithInjector(provider, this);
}
}
if (parent != null) {
return parent._getProviderWithInjectorForKey(key, resolving);
}
if (allowImplicitInjection) {
return new _ProviderWithInjector(new TypeProvider(key.type), this);
}
throw new NoProviderError(
error(resolving, 'No provider found for ${key}!', key));
}

bool _checkKeyConditions(Key key, ResolutionContext resolving) {
if (_PRIMITIVE_TYPES.contains(key)) {
throw new NoProviderError(
Expand Down Expand Up @@ -200,9 +183,24 @@ abstract class BaseInjector implements Injector, ObjectFactory {
} else if (key is! Key) {
throw 'forceNewInstances must be List<Key|Type>';
}
var providerWithInjector =
_getProviderWithInjectorForKey(key, resolving);
var provider = providerWithInjector.provider;

// This code is pasted from getInstanceByKey for performance
var provider = key.id < _providers.length ? _providers[key.id] : null;
var injector = this;
while (provider == null){
if (injector.parent == null){
if (allowImplicitInjection) {
provider = new TypeProvider(key.type);
break;
}
throw new NoProviderError(
error(resolving, 'No provider found for ${key}!', key));
}
injector = injector.parent;
provider = key.id < injector._providers.length ?
injector._providers[key.id] : null;
}

forceNew.bindByKey(key,
toFactory: (Injector inj) =>
provider.get(this, inj, inj as ObjectFactory, resolving),
Expand All @@ -222,12 +220,6 @@ abstract class BaseInjector implements Injector, ObjectFactory {
ResolutionContext resolving);
}

class _ProviderWithInjector {
final Provider provider;
final BaseInjector injector;
_ProviderWithInjector(this.provider, this.injector);
}

/**
* A node in a depth-first search tree of the dependency DAG.
*/
Expand Down

0 comments on commit d2a38b5

Please sign in to comment.