-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
toSingle causes excessive stack traces #4594
Comments
Could you post a unit test that shows the problem. The stacktrace refers to a bunch of mappings which I guess is in |
Here is a unit test that demonstrates the situation: package com.example;
import junit.framework.Assert;
import org.junit.Test;
import rx.Observable;
import rx.Single;
import rx.functions.Action1;
import rx.subjects.PublishSubject;
public class ExampleUnitTest {
final int ITERATIONS = 10;
private Action1<Integer> assertStack(final int baseStack, final int additionalFrames, final int iterationFrames) {
return o -> Assert.assertEquals(baseStack + additionalFrames + ITERATIONS * iterationFrames, Thread.currentThread().getStackTrace().length);
}
@Test
public void testFlatMap() {
int baseStack = Thread.currentThread().getStackTrace().length;
PublishSubject<Integer> subject = PublishSubject.create();
Single<Integer> single1 = subject.toSingle().flatMap(integer -> {
Single<Integer> modified = Single.just(integer);
for (int i = 0; i < ITERATIONS; i++) {
modified = modified.map(n -> n + 1);
}
return modified;
});
Observable<Integer> observable = subject.concatMap(integer -> {
Observable<Integer> modified = Observable.just(integer);
for (int i = 0; i < ITERATIONS; i++) {
modified = modified.map(n -> n + 1);
}
return modified;
});
single1.subscribe(assertStack(baseStack, 34, 12));
observable.subscribe(assertStack(baseStack, 18, 5));
observable.toSingle().subscribe(assertStack(baseStack, 14, 0));
subject.onNext(0);
subject.onCompleted();
}
} The first subscription is my initial code. The third subscription is the comparison I was making. The second subscription makes clear that I was seeing such an improvement because the final |
We may be able to reduce the stack dept a bit but the problem is this: for (int i = 0; i < ITERATIONS; i++) {
modified = modified.map(n -> n + 1);
} Your composition gets unconventionally long this way and you might want to find another way of having that many maps chained (like collect them into
|
I edited my previous comment since the stack sizes were actually for |
I looked into the trampoline scheduler recently, and it looks like adding it into the chain with |
I see. The whole |
For the sake of completeness, here's a simpler (and perhaps more fair) test demonstrating the difference between package com.example;
import junit.framework.Assert;
import org.junit.Test;
import rx.Observable;
import rx.Single;
import rx.functions.Action1;
import rx.subjects.PublishSubject;
public class ExampleUnitTest {
final int ITERATIONS = 20;
private Action1<Integer> assertStack(final int baseStack, final int additionalFrames, final int iterationFrames) {
return o -> Assert.assertEquals(baseStack + additionalFrames + ITERATIONS * iterationFrames, Thread.currentThread().getStackTrace().length);
}
@Test
public void testFlatMap() {
int baseStack = Thread.currentThread().getStackTrace().length;
PublishSubject<Integer> subject = PublishSubject.create();
Single<Integer> single1 = subject.toSingle();
for (int i = 0; i < ITERATIONS; i++) {
single1 = single1.flatMap(integer -> Single.just(integer + 1));
}
Single<Integer> single2 = subject.toSingle();
for (int i = 0; i < ITERATIONS; i++) {
single2 = single2.toObservable().concatMap(integer -> Observable.just(integer + 1)).toSingle();
}
single1.subscribe(assertStack(baseStack, 10, 24));
single2.subscribe(assertStack(baseStack, 10, 8));
subject.onNext(0);
subject.onCompleted();
}
} It seems that using private Single.Transformer<Integer, Integer> transformer2(final Func1<Integer, Single<Integer>> mapper) {
return integerSingle -> integerSingle.toObservable().concatMap(it -> mapper.call(it).toObservable()).toSingle();
} |
Posted #4648. May not get all reduction but it's a base for further compaction. |
Thanks for looking into this. On Fri, Sep 30, 2016 at 2:40 PM, David Karnok [email protected]
|
Closing via #4648 |
I have the following code:
which produces the following stack trace:
When I change the code to:
The stack trace I get is:
This is happening on RxJava 1.1.9
The text was updated successfully, but these errors were encountered: