-
Notifications
You must be signed in to change notification settings - Fork 11
Improve performance 20%-110% #14
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
Conversation
CLA Available |
* Index of the string bytes within {@link vpack}, | ||
* i.e. tag byte and length are somewhere before this index. | ||
*/ | ||
private int start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure about this decision. Starting at the tag byte would make it more similar to VPackSlice
, but it would add a bit more complexity to the compareToBytes
operations. Those comparisons are on the hot path for the O(ln n)
path queries and for sorting the offset table while constructing the object.
I couldn't think of a good way to make this class private, so it's probably worth giving it some thought before merging so we don't break compatibility later.
@mpv1989 @hkernbach What do you think?
@htmldoug Thanks for contributing! |
@rashtao any idea when you'll get to this or should I fork? |
@htmldoug thanks for the reminder, we will likely review it in the next weeks. |
I'll give this another two weeks then probably close and fork. |
It is sad to see that such great (and obvious!) performance improvements take so long to get accepted. |
@htmldoug I am reviewing the PR, but there are some points unclear to me:
I would respectively suggest you to:
Also, upgrading to java 7 as lower required java version, would enable us to use ByteBuffers, thus avoiding Thanks for contributing and sorry for the late reply! |
I added the
done!
Done. Replaced with:
Good observation. Looks like the results of that benchmark vary significantly between jvm forks. Setting
|
I think I've figured out and fixed the javadoc warnings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Hey @rashtao, how would this work? I only have a light understanding of |
@htmldoug |
I'm still not entirely sure how |
Why not just implement an OutputStream that stores everything in a List<byte[]>? Then we could have a toByteArray() method that copies the whole content to a single byte array (e.g. for Slice) and write* methods that are optimized to use the original byte arrays directly. The only issue is the Builder.remove() method that needs some more attention. For a more complex solution Netty has CompositeByteBuf which works similarly, but uses ByteBuffers for storage. |
@siilike, yeah, that'd be an improvement and there's good precedent for that. Dreaming about ideal state for a moment, I'd love the option to be able to back both This would require decoupling |
I would suggest encapsulating all the buffer operations in one single class, call it eg. VPackSliceBuffer, and implementing there all the methods for manipulating the buffer. The first implementation can simply delegate the underlying byte array operations. Once we have it we can test and benchmark different implementations. We can even think about having different buffer implementations and leave to the user the possibility to choose which one to use. Also I would move the discussion to https://arangodb-community.slack.com/archives/C5T51CW2J so we can get feedback and opinions from the community. |
"Don't have an account on this workspace yet? |
Sorry @siilike , you can register here: https://slack.arangodb.com/ |
Summary
Adds simple benchmarks for
VPackBuilder
,VPackSlice
, andVPackParser
. Improves runtime performance by ~110% withinVPackBuilder
/VPackSlice
.String
=>VPackSlice
is dominated by json parsing and remains about the same.Results
https://jmh.morethan.io/?sources=https://gist.githubusercontent.com/htmldoug/d292b301fdc3ec66cd7098e4ee54e965/raw/14e54eb2c9b153ba81931d16b276511eb3796f7f/jmh-result-before.json,https://gist.githubusercontent.com/htmldoug/d292b301fdc3ec66cd7098e4ee54e965/raw/14e54eb2c9b153ba81931d16b276511eb3796f7f/jmh-result-optimized.json
Context
I don't use arangodb, but I'm interested in using velocypack to reduce the heap usage of my json processing. I recently saw a 35 MB byte array get parsed to 270 MB of heap by play-json's
JsValue
. Case classes ate my RAM inspired backing theJsValue
by aVPackSlice
and it drops the heap usage to ~38 MB for the cost of about 33% more CPU time.JMH + JFR + JMC revealed some some low-hanging fruit to cut the extra CPU time roughly in half for my use case. I also benched a real world example of String => VPackSlice from arrangodb/velocypack. The majority of time is spent on json parsing, although throughput still improved by 20%.
Optimizations
The gains come mostly from reducing UTF-8 encoding by
string.getBytes()
and replacingHashMap<Integer, T>
lookups for sequential indexes with simpleT[]
arrays.CLA
I've emailed a signed CLA to cla@arangodb.com.