From 0b43a7a9b6dcdb45aea3ce423e02ed53a06b1f79 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Thu, 24 Jan 2019 14:14:08 +0100 Subject: [PATCH] perf(internal): optimize Subscription#add() for the common case 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. --- src/internal/Subscription.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/internal/Subscription.ts b/src/internal/Subscription.ts index 7e110d107f..29ce9f8533 100644 --- a/src/internal/Subscription.ts +++ b/src/internal/Subscription.ts @@ -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 = ( teardown); - + let 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(); @@ -168,13 +160,21 @@ export class Subscription implements SubscriptionLike { subscription._subscriptions = [tmp]; } break; - default: + default: { + if (!(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;