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

Improve performance of NewThreadWorker, disable search for setRemoveOnCancelPolicy() on Android API < 21 #3121

Merged

Conversation

artem-zinnatullin
Copy link
Contributor

Resolves #3119.

This PR adds methods for detecting Android API Version and disables NewThreadWorker.tryEnableCancelPolicy() on Android API < 21 which has significant performance cost on Android.

PR also improves performance of NewThreadWorker.tryEnableCancelPolicy() via caching Reflection.

@@ -50,6 +53,16 @@
PURGE = new AtomicReference<ScheduledExecutorService>();
PURGE_FORCE = Boolean.getBoolean(PURGE_FORCE_KEY);
PURGE_FREQUENCY = Integer.getInteger(FREQUENCY_KEY, 1000);

// Cached to prevent method call
IS_ANDROID = PlatformDependent.isAndroid();
Copy link
Member

Choose a reason for hiding this comment

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

This is redundant with the other checks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so, we're trying to enable cancel policy if current platform is not Android or if it's Android and API >= 21, that's why I have 2 separate booleans.

Or maybe I just don't see easier way.

Copy link
Member

Choose a reason for hiding this comment

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

You are checking if the API is null which is equivalent (and thus redundant) with this boolean.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, but then I use IS_ANDROID on line 127. I've improved IS_ANDROID initialization.

@artem-zinnatullin
Copy link
Contributor Author

Checked on JVM (Java 8), Android 4.1.2 (API 16), Android 5.1.1 (API 22).

@artem-zinnatullin artem-zinnatullin force-pushed the android-setRemoveOnCancelPolicy branch 2 times, most recently from 85d2e83 to 1cd7141 Compare July 29, 2015 18:52
private static final boolean IS_ANDROID = isAndroid0();
// Will be null if current platform is not Android
// Or if Android API Version can not be resolved.
private static final Integer ANDROID_API_VERSION = resolveAndroidApiVersion();
Copy link
Member

Choose a reason for hiding this comment

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

Is there an API version 0? If not, we could use int here so there is no need for unboxing and null checking elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, there is no API version 0 as far as I know, we can also use -1 as Not-Android-Platform value and even create a constant.

Copy link
Member

Choose a reason for hiding this comment

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

Nope. Great idea! RxJava doesn't support anything below API 9 anyway.

final Integer androidApiVersion = PlatformDependent.getAndroidApiVersion();

// Cached to prevent method call
IS_ANDROID = androidApiVersion != null;
Copy link
Member

Choose a reason for hiding this comment

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

You can still eliminate this variable altogether. The same check is included in the other.

@artem-zinnatullin artem-zinnatullin changed the title Disable search for ScheduledExecutorService.setRemoveOnCancelPolicy() on Android API < 21 Improve performance of NewThreadWorker.tryEnableCancelPolicy(), disable search for ScheduledExecutorService.setRemoveOnCancelPolicy() on Android API < 21 Jul 29, 2015
private static final boolean IS_ANDROID = isAndroid0();
/**
* Constant value of Android API Version which means that current platform is not Android.
* We could use {@link Integer} and {@code null}, but we want to avoid boxing/unboxing.
Copy link
Member

Choose a reason for hiding this comment

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

Second sentence is not useful to retain.

}

@Test
public void tryEnableCancelPolicyShouldBeSkipped() throws NoSuchFieldException, IllegalAccessException {
Copy link
Member

Choose a reason for hiding this comment

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

This looks rather dangerous. What I'd do is to have a package-private method tryEnableCancelPolicy(ScheduledExecutor executor, boolean tryEnable) so the test can inject the necessary value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, a separate method just for injecting value which can completely disable it… Not sure I am following this (on Android we have some limits on the quantity of methods in the app, this will increment it just for test purposes), let's just remove this test for now?

Or I can remove private modifier from SHOULD_TRY_ENABLE_CANCEL_POLICY and make this test more "static", reflection will only change the value of this field.

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 rather not have this test for now. All other changes appear to be okay. If you update the PR, I'll merge it.

@artem-zinnatullin artem-zinnatullin changed the title Improve performance of NewThreadWorker.tryEnableCancelPolicy(), disable search for ScheduledExecutorService.setRemoveOnCancelPolicy() on Android API < 21 Improve performance of NewThreadWorker, disable search for setRemoveOnCancelPolicy() on Android API < 21 Jul 30, 2015
@artem-zinnatullin
Copy link
Contributor Author

Fixed all comments, removed test with reflection, added more javadoc and comments, tests are now compilable on JDK 6 (didn't check but they should work fine). @akarnokd, @JakeWharton PTAL

/**
* Resolves version of Android API.
*
* @return version of Android API or {@code null} if version can not be resolved.
Copy link
Member

Choose a reason for hiding this comment

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

This no longer returns null but ANDROID_API_VERSION_IS_NOT_ANDROID.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Disable search for ScheduledExecutorService.setRemoveOnCancelPolicy() on Android API < 21
@akarnokd
Copy link
Member

akarnokd commented Aug 1, 2015

Great, thanks!

akarnokd added a commit that referenced this pull request Aug 1, 2015
…ncelPolicy

Improve performance of NewThreadWorker, disable search for setRemoveOnCancelPolicy() on Android API < 21
@akarnokd akarnokd merged commit a3a0b1f into ReactiveX:1.x Aug 1, 2015
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