Skip to content

Commit 1a5ce9a

Browse files
committed
reduce gc pressure by using singleton Operators for single, distinct, distinctUntilChanged, onBackpressureBuffer, isEmpty
1 parent 9fb5614 commit 1a5ce9a

File tree

5 files changed

+87
-9
lines changed

5 files changed

+87
-9
lines changed

src/main/java/rx/Observable.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,7 +2295,7 @@ public final Observable<Observable<T>> nest() {
22952295
* @see <a href="http://reactivex.io/documentation/operators/empty-never-throw.html">ReactiveX operators documentation: Never</a>
22962296
*/
22972297
public final static <T> Observable<T> never() {
2298-
return new NeverObservable<T>();
2298+
return NeverObservable.create();
22992299
}
23002300

23012301
/**
@@ -4026,7 +4026,7 @@ public final <T2> Observable<T2> dematerialize() {
40264026
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
40274027
*/
40284028
public final Observable<T> distinct() {
4029-
return lift(new OperatorDistinct<T, T>(UtilityFunctions.<T>identity()));
4029+
return lift(OperatorDistinct.<T> create());
40304030
}
40314031

40324032
/**
@@ -4064,7 +4064,7 @@ public final <U> Observable<T> distinct(Func1<? super T, ? extends U> keySelecto
40644064
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
40654065
*/
40664066
public final Observable<T> distinctUntilChanged() {
4067-
return lift(new OperatorDistinctUntilChanged<T, T>(UtilityFunctions.<T>identity()));
4067+
return lift(OperatorDistinctUntilChanged.<T> create());
40684068
}
40694069

40704070
/**
@@ -4959,8 +4959,13 @@ public final Observable<T> ignoreElements() {
49594959
* @return an Observable that emits a Boolean
49604960
* @see <a href="http://reactivex.io/documentation/operators/contains.html">ReactiveX operators documentation: Contains</a>
49614961
*/
4962+
@SuppressWarnings("unchecked")
49624963
public final Observable<Boolean> isEmpty() {
4963-
return lift(new OperatorAny<T>(UtilityFunctions.alwaysTrue(), true));
4964+
return lift((OperatorAny<T>) HolderAnyForEmpty.INSTANCE);
4965+
}
4966+
4967+
private static class HolderAnyForEmpty {
4968+
static final OperatorAny<?> INSTANCE = new OperatorAny<Object>(UtilityFunctions.alwaysTrue(), true);
49644969
}
49654970

49664971
/**
@@ -5226,7 +5231,7 @@ public final Boolean call(T t) {
52265231
* @see <a href="http://reactivex.io/documentation/operators/backpressure.html">ReactiveX operators documentation: backpressure operators</a>
52275232
*/
52285233
public final Observable<T> onBackpressureBuffer() {
5229-
return lift(new OperatorOnBackpressureBuffer<T>());
5234+
return lift(OperatorOnBackpressureBuffer.<T> create());
52305235
}
52315236

52325237
/**
@@ -6709,7 +6714,7 @@ public final Observable<T> share() {
67096714
* @see <a href="http://reactivex.io/documentation/operators/first.html">ReactiveX operators documentation: First</a>
67106715
*/
67116716
public final Observable<T> single() {
6712-
return lift(new OperatorSingle<T>());
6717+
return lift(OperatorSingle.<T>create());
67136718
}
67146719

67156720
/**
@@ -9276,7 +9281,22 @@ public final <T2, R> Observable<R> zipWith(Observable<? extends T2> other, Func2
92769281
* the type of item (not) emitted by the Observable
92779282
*/
92789283
private static class NeverObservable<T> extends Observable<T> {
9279-
public NeverObservable() {
9284+
9285+
private static class Holder {
9286+
static final NeverObservable<?> INSTANCE = new NeverObservable<Object>();
9287+
}
9288+
9289+
/**
9290+
* Returns a singleton instance of NeverObservble (cast to the generic type).
9291+
*
9292+
* @return
9293+
*/
9294+
@SuppressWarnings("unchecked")
9295+
static <T> NeverObservable<T> create() {
9296+
return (NeverObservable<T>) Holder.INSTANCE;
9297+
}
9298+
9299+
NeverObservable() {
92809300
super(new OnSubscribe<T>() {
92819301

92829302
@Override

src/main/java/rx/internal/operators/OperatorDistinct.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717

1818
import java.util.HashSet;
1919
import java.util.Set;
20+
2021
import rx.Observable.Operator;
2122
import rx.Subscriber;
2223
import rx.functions.Func1;
24+
import rx.internal.util.UtilityFunctions;
2325

2426
/**
2527
* Returns an Observable that emits all distinct items emitted by the source.
@@ -29,6 +31,21 @@
2931
*/
3032
public final class OperatorDistinct<T, U> implements Operator<T, T> {
3133
final Func1<? super T, ? extends U> keySelector;
34+
35+
private static class Holder {
36+
static final OperatorDistinct<?,?> INSTANCE = new OperatorDistinct<Object,Object>(UtilityFunctions.<Object>identity());
37+
}
38+
39+
/**
40+
* Returns a singleton instance of OperatorDistinct that was built using
41+
* the identity function for comparison (<code>new OperatorDistinct(UtilityFunctions.identity())</code>).
42+
*
43+
* @return Operator that emits distinct values only (regardless of order) using the identity function for comparison
44+
*/
45+
@SuppressWarnings("unchecked")
46+
public static <T> OperatorDistinct<T,T> create() {
47+
return (OperatorDistinct<T, T>) Holder.INSTANCE;
48+
}
3249

3350
public OperatorDistinct(Func1<? super T, ? extends U> keySelector) {
3451
this.keySelector = keySelector;

src/main/java/rx/internal/operators/OperatorDistinctUntilChanged.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import rx.Observable.Operator;
1919
import rx.Subscriber;
2020
import rx.functions.Func1;
21+
import rx.internal.util.UtilityFunctions;
2122

2223
/**
2324
* Returns an Observable that emits all sequentially distinct items emitted by the source.
@@ -26,6 +27,22 @@
2627
*/
2728
public final class OperatorDistinctUntilChanged<T, U> implements Operator<T, T> {
2829
final Func1<? super T, ? extends U> keySelector;
30+
31+
private static class Holder {
32+
static final OperatorDistinctUntilChanged<?,?> INSTANCE = new OperatorDistinctUntilChanged<Object,Object>(UtilityFunctions.identity());
33+
}
34+
35+
36+
/**
37+
* Returns a singleton instance of OperatorDistinctUntilChanged that was built using
38+
* the identity function for comparison (<code>new OperatorDistinctUntilChanged(UtilityFunctions.identity())</code>).
39+
*
40+
* @return Operator that emits sequentially distinct values only using the identity function for comparison
41+
*/
42+
@SuppressWarnings("unchecked")
43+
public static <T> OperatorDistinctUntilChanged<T,T> create() {
44+
return (OperatorDistinctUntilChanged<T, T>) Holder.INSTANCE;
45+
}
2946

3047
public OperatorDistinctUntilChanged(Func1<? super T, ? extends U> keySelector) {
3148
this.keySelector = keySelector;

src/main/java/rx/internal/operators/OperatorOnBackpressureBuffer.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,16 @@ public class OperatorOnBackpressureBuffer<T> implements Operator<T, T> {
3131
private final Long capacity;
3232
private final Action0 onOverflow;
3333

34-
public OperatorOnBackpressureBuffer() {
34+
private static class Holder {
35+
static final OperatorOnBackpressureBuffer<?> INSTANCE = new OperatorOnBackpressureBuffer<Object>();
36+
}
37+
38+
@SuppressWarnings("unchecked")
39+
public static <T> OperatorOnBackpressureBuffer<T> create() {
40+
return (OperatorOnBackpressureBuffer<T>) Holder.INSTANCE;
41+
}
42+
43+
private OperatorOnBackpressureBuffer() {
3544
this.capacity = null;
3645
this.onOverflow = null;
3746
}

src/main/java/rx/internal/operators/OperatorSingle.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,22 @@ public final class OperatorSingle<T> implements Operator<T, T> {
3232
private final boolean hasDefaultValue;
3333
private final T defaultValue;
3434

35-
public OperatorSingle() {
35+
private static class Holder {
36+
final static OperatorSingle<?> INSTANCE = new OperatorSingle<Object>();
37+
}
38+
39+
/**
40+
* Returns a singleton instance of OperatorSingle (if the stream is empty or has
41+
* more than one element an error will be emitted) that is cast to the generic type.
42+
*
43+
* @return a singleton instance of an Operator that will emit a single value only unless the stream has zero or more than one element in which case it will emit an error.
44+
*/
45+
@SuppressWarnings("unchecked")
46+
public static <T> OperatorSingle<T> create() {
47+
return (OperatorSingle<T>) Holder.INSTANCE;
48+
}
49+
50+
private OperatorSingle() {
3651
this(false, null);
3752
}
3853

0 commit comments

Comments
 (0)