Skip to content

Commit

Permalink
perf(internal): optimize Subscription#add() for the common case
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 committed Jan 24, 2019
1 parent 83a8485 commit 0b43a7a
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 0b43a7a

Please sign in to comment.