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

Performance optimization for primitive Dynamic***Property classes #369

Merged
merged 12 commits into from Aug 19, 2016

Conversation

kerumai
Copy link

@kerumai kerumai commented Nov 30, 2015

This is an optimization to reduce the cpu hotspots I was seeing under load with usage of DynamicBooleanProperty/DynamicIntProperty getValue implementation.
As we use DynamicBooleanProperty's very frequently for feature-flagging in zuul, I was seeing this quite high up when profiling zuul under high load. It seems to be caused by overhead around autoboxing of the value objects to primitives (although I haven't verified this).

I initially added a helper class in zuul for this - https://github.com/Netflix/zuul/blob/2.x/zuul-core/src/main/java/com/netflix/zuul/properties/CachedProperties.java - but would like to apply the same principle in archaius itself, and so have done this PR.

The PR basically changes the Dynamic{Primitive}Property classes to store the cached primitive value, and update it using the callback mechanism. And then change the existing get() method to return this cached value instead of boxing the property value object.

I've included a basic benchmarking class that compares performance of the old and new implementations for boolean. See CachedPropertiesPerfTest.

- Added a simple benchmark to compare the implementations.

- Added an attempt at DynamicPrimitiveBooleanProperty which (unlike my CachedProperties) extends the normal PropertyWrapper.
… values

Changed tack to doing this to the existing classes instead of adding new implementations, so that existing users of get
the benefits too.

Added some tests to verify that updating of property values also updates the cached primitives.
@cloudbees-pull-request-builder

archaius-pull-requests #324 FAILURE
Looks like there's a problem with this pull request

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #159 FAILURE
Looks like there's a problem with this pull request

@cloudbees-pull-request-builder

archaius-pull-requests #325 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #160 FAILURE
Looks like there's a problem with this pull request

* @return
*/
private boolean chooseValue() {
Boolean propValue = this.prop == null ? null : this.prop.getBoolean();
Copy link

Choose a reason for hiding this comment

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

The null check for the prop field is unnecessary.

Copy link

Choose a reason for hiding this comment

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

This method could be just the previous body of the get method: return prop.getBoolean(defaultValue).booleanValue(). The boxing and unboxing that will occur when the property value changes will be off the hot-path and a minor overhead for clearer code.

Copy link
Author

Choose a reason for hiding this comment

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

Actually, all of the overhead does seem to be caused by this. I've added another benchmark comparison to the CachedPropertiesPerfTest to illustrate. eg:

Original DynamiceBooleanProperty totalled 7087 ms.
New DynamicBooleanProperty totalled 1252 ms.
New DynamicBooleanProperty with old get() totalled 7129 ms.

Copy link

Choose a reason for hiding this comment

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

I wasn't suggesting reverting the change to the get method, which is what your new test is effectively doing, but rather to put the old code from the get method into the new chooseValue method. There it would be execute just once per property value change.

Copy link
Author

Choose a reason for hiding this comment

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

Ah I see what you mean now. Sorry for the confusion. I'll do that now, thanks.

- Replaced usage of the callback mechanism with overriding the propertyChanged() method.

- Removed unnecessary null check.

- Added a comparison with previous get() method impl in CachedPropertiesPerfTest.
@cloudbees-pull-request-builder

archaius-pull-requests #326 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #161 FAILURE
Looks like there's a problem with this pull request

@cloudbees-pull-request-builder

archaius-pull-requests #327 SUCCESS
This pull request looks good

@pstout
Copy link

pstout commented Dec 2, 2015

LGTM

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #162 FAILURE
Looks like there's a problem with this pull request


@Override
protected void propertyChanged() {
super.propertyChanged();
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little wary of calling super here. It's a no-op there at super, so overhead is less of concern. But it maybe confusing for people down the road who might expect if they make the change in super, it would take effect in subclasses as well.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah thats true. Will change that now.

@cloudbees-pull-request-builder

archaius-pull-requests #329 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #164 FAILURE
Looks like there's a problem with this pull request

…hanging the existing Dynamic*Property classes
@cloudbees-pull-request-builder

archaius-pull-requests #342 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #176 FAILURE
Looks like there's a problem with this pull request

@cloudbees-pull-request-builder

archaius-pull-requests #343 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

NetflixOSS » archaius » archaius-pull-requests #177 FAILURE
Looks like there's a problem with this pull request

@@ -39,4 +39,4 @@ public double get() {
public Double getValue() {
return get();
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

what're all these format changes? can we get rid of those format changes only files?

Copy link
Author

Choose a reason for hiding this comment

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

Absolutely.

@howardyuan howardyuan merged commit b909f75 into Netflix:master Aug 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants