From 40c43f74326b50198fef9763d1e079bbf8e02f1b Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Tue, 26 Jan 2016 15:54:22 -0800 Subject: [PATCH] perf(groupBy): remove tryCatch/errorObject for custom tryCatching, 38% faster. --- src/operator/groupBy.ts | 89 ++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/src/operator/groupBy.ts b/src/operator/groupBy.ts index c819554d03..dc07660f96 100644 --- a/src/operator/groupBy.ts +++ b/src/operator/groupBy.ts @@ -4,8 +4,6 @@ import {Observable} from '../Observable'; import {Subject} from '../Subject'; import {Map} from '../util/Map'; import {FastMap} from '../util/FastMap'; -import {tryCatch} from '../util/tryCatch'; -import {errorObject} from '../util/errorObject'; /** * Groups the items emitted by an Observable according to a specified criterion, @@ -56,48 +54,67 @@ class GroupBySubscriber extends Subscriber { this.add(destination); } - protected _next(x: T): void { - let key = tryCatch(this.keySelector)(x); - if (key === errorObject) { - this.error(errorObject.e); - } else { - let groups = this.groups; - const elementSelector = this.elementSelector; - const durationSelector = this.durationSelector; - - if (!groups) { - groups = this.groups = typeof key === 'string' ? new FastMap() : new Map(); - } + protected _next(value: T): void { + let key: any; + try { + key = this.keySelector(value); + } catch (err) { + this.error(err); + return; + } + this._group(value, key); + } - let group = groups.get(key); + private _group(value: T, key: K) { + let groups = this.groups; - if (!group) { - groups.set(key, group = new Subject()); - let groupedObservable = new GroupedObservable(key, group, this.refCountSubscription); + if (!groups) { + groups = this.groups = typeof key === 'string' ? new FastMap() : new Map(); + } - if (durationSelector) { - let duration = tryCatch(durationSelector)(new GroupedObservable(key, group)); - if (duration === errorObject) { - this.error(errorObject.e); - } else { - this.add(duration.subscribe(new GroupDurationSubscriber(key, group, this))); - } - } + let group = groups.get(key); - this.destination.next(groupedObservable); - } + if (!group) { + groups.set(key, group = new Subject()); + let groupedObservable = new GroupedObservable(key, group, this.refCountSubscription); - if (elementSelector) { - let value = tryCatch(elementSelector)(x); - if (value === errorObject) { - this.error(errorObject.e); - } else { - group.next(value); + if (this.durationSelector) { + if (!this._tryDuration(key, group)) { + return; } - } else { - group.next(x); } + + this.destination.next(groupedObservable); + } + + if (this.elementSelector) { + this._tryElementSelector(value, group); + } else { + group.next(value); + } + } + + private _tryElementSelector(value: T, group: Subject) { + let result: any; + try { + result = this.elementSelector(value); + } catch (err) { + this.error(err); + return; + } + group.next(result); + } + + private _tryDuration(key: K, group: any): boolean { + let duration: any; + try { + duration = this.durationSelector(new GroupedObservable(key, group)); + } catch (err) { + this.error(err); + return false; } + this.add(duration.subscribe(new GroupDurationSubscriber(key, group, this))); + return true; } protected _error(err: any): void {