Skip to content

Commit

Permalink
perf(internal): optimize Subscription#add() for the common case (#4489)
Browse files Browse the repository at this point in the history
This removes unnecessary checks on the `teardown` parameter upfront, and
instead moves these checks into the appropriate branches guarded by the
type check. This way we get the same behavior, but with fewer checks and
smaller code size.

Also optimize adding the child `subscription` to `this._subscriptions`
for the common case that there were no previous subscriptions.
  • Loading branch information
bmeurer authored and benlesh committed Jan 24, 2019
1 parent fc84a00 commit bdd201c
Showing 1 changed file with 16 additions and 16 deletions.
32 changes: 16 additions & 16 deletions src/internal/Subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,13 @@ export class Subscription implements SubscriptionLike {
* list.
*/
add(teardown: TeardownLogic): Subscription {
if (!teardown || (teardown === Subscription.EMPTY)) {
return Subscription.EMPTY;
}

if (teardown === this) {
return this;
}

let subscription = (<Subscription> teardown);

let subscription = (<Subscription>teardown);
switch (typeof teardown) {
case 'function':
subscription = new Subscription(<(() => void) > teardown);
subscription = new Subscription(<(() => void)>teardown);
case 'object':
if (subscription.closed || typeof subscription.unsubscribe !== 'function') {
if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') {
// This also covers the case where `subscription` is `Subscription.EMPTY`, which is always in `closed` state.
return subscription;
} else if (this.closed) {
subscription.unsubscribe();
Expand All @@ -168,13 +160,21 @@ export class Subscription implements SubscriptionLike {
subscription._subscriptions = [tmp];
}
break;
default:
default: {
if (!(<any>teardown)) {
return Subscription.EMPTY;
}
throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');
}
}

const subscriptions = this._subscriptions || (this._subscriptions = []);

subscriptions.push(subscription);
// Optimize for the common case when adding the first subscription.
const subscriptions = this._subscriptions;
if (subscriptions) {
subscriptions.push(subscription);
} else {
this._subscriptions = [subscription];
}
subscription._addParent(this);

return subscription;
Expand Down

0 comments on commit bdd201c

Please sign in to comment.