Skip to content
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

Defer creation of the TimeoutException when using the Single.timeout() operator #5250

Merged
merged 2 commits into from
Apr 2, 2017

Conversation

dhendry
Copy link

@dhendry dhendry commented Mar 31, 2017

Use a defer instead of simply other = Single.error(new TimeoutException()) since instantiating an exception will cause the current stack trace to be inspected and that overhead should only be incurred when a timeout actually happens.

I caught this problem as I was investigating unusually high CPU usage in one of the systems I operate. When measuring the impact of this change in a real world situation that makes only moderate use of this operator, I observed a 11% reduction in CPU usage.

@dhendry
Copy link
Author

dhendry commented Mar 31, 2017

Please let me know if there is anything about this PR that needs to change in order to get this fix merged as the performance improvement seems to be reasonably significant.

// since instantiating an exception will cause the current stack trace to be inspected
// and we only want to incur that overhead when a timeout actually happens.
other = Single.<T>defer(new Func0<Single<T>>()
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go on the previous line after a space.

{
@Override
public Single<T> call()
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go on the previous line after a space.

@JakeWharton
Copy link
Contributor

Is this also a problem without timeout() operators on other stream types? And also what about 2.x?

@codecov
Copy link

codecov bot commented Mar 31, 2017

Codecov Report

Merging #5250 into 1.x will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff              @@
##                1.x    #5250      +/-   ##
============================================
+ Coverage     84.36%   84.38%   +0.02%     
- Complexity     2883     2884       +1     
============================================
  Files           290      290              
  Lines         18124    18125       +1     
  Branches       2479     2479              
============================================
+ Hits          15290    15295       +5     
+ Misses         1965     1964       -1     
+ Partials        869      866       -3
Impacted Files Coverage Δ Complexity Δ
src/main/java/rx/Single.java 73.96% <100%> (+0.09%) 82 <0> (ø) ⬇️
...java/rx/internal/schedulers/ExecutorScheduler.java 77.46% <0%> (-4.23%) 2% <0%> (ø)
...rx/internal/operators/OnSubscribeFromIterable.java 91.46% <0%> (-2.44%) 5% <0%> (ø)
...ava/rx/internal/util/BackpressureDrainManager.java 66.66% <0%> (-1.24%) 20% <0%> (-1%)
...main/java/rx/internal/operators/OperatorMerge.java 87.06% <0%> (ø) 7% <0%> (ø) ⬇️
...n/java/rx/subjects/SubjectSubscriptionManager.java 81.42% <0%> (+0.71%) 15% <0%> (ø) ⬇️
...n/java/rx/internal/operators/CachedObservable.java 84.78% <0%> (+1.08%) 6% <0%> (ø) ⬇️
...ternal/operators/OperatorOnBackpressureLatest.java 82.85% <0%> (+1.9%) 3% <0%> (ø) ⬇️
.../rx/internal/schedulers/CachedThreadScheduler.java 89.32% <0%> (+1.94%) 6% <0%> (ø) ⬇️
.../java/rx/internal/operators/BackpressureUtils.java 70.45% <0%> (+2.27%) 28% <0%> (+1%) ⬆️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e37d1a7...35f5fc2. Read the comment docs.

@dhendry
Copy link
Author

dhendry commented Mar 31, 2017

@JakeWharton I havent done a super exhaustive audit but, it does not look like this is an issue with any of the other timeout operators in the 1.x branch or the single timeout in the 2.x branch

Copy link
Member

@akarnokd akarnokd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you could fix all of 1.x with this problem, that would be great.

@@ -2254,7 +2254,15 @@ public final Completable toCompletable() {
*/
public final Single<T> timeout(long timeout, TimeUnit timeUnit, Single<? extends T> other, Scheduler scheduler) {
if (other == null) {
other = Single.<T> error(new TimeoutException());
// Use a defer instead of simply other = Single.error(new TimeoutException())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd inline this into SingleTimeout, that way, there are no extra instances unless necessary.

@akarnokd akarnokd merged commit bc40a84 into ReactiveX:1.x Apr 2, 2017
@akarnokd akarnokd added this to the 1.3 milestone Apr 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants