-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Optimize writing numeric values. #1635
base: main
Are you sure you want to change the base?
Conversation
I like this, it looks similar to my PR at #1629 which try writing byte per byte if there is available space to straight use the same buffer ❤️ |
* @throws java.nio.BufferOverflowException if there are fewer than 4 bytes remaining in this buffer | ||
* @throws java.nio.ReadOnlyBufferException if this buffer is read-only | ||
*/ | ||
ByteBuf putInt(int b); |
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.
Given that the interface includes the warning:
This interface is not frozen yet, and methods may be added in a minor release, so beware implementing this yourself we are justified in adding new methods to this class.
it is permissible to add new methods to this class.
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.
Add @since
to the javadoc for all the new methods.
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.
Like the changes - just a couple of nits.
* @throws java.nio.BufferOverflowException if there are fewer than 4 bytes remaining in this buffer | ||
* @throws java.nio.ReadOnlyBufferException if this buffer is read-only | ||
*/ | ||
ByteBuf putInt(int b); |
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.
Add @since
to the javadoc for all the new methods.
driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java
Outdated
Show resolved
Hide resolved
driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java
Outdated
Show resolved
Hide resolved
driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java
Outdated
Show resolved
Hide resolved
class ByteBufTest { | ||
|
||
static Stream<BufferProvider> bufferProviders() { | ||
return Stream.of(new ByteBufSpecification.NettyBufferProvider(), new SimpleBufferProvider()); |
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.
👍
driver-core/src/test/unit/com/mongodb/internal/connection/ByteBufTest.java
Show resolved
Hide resolved
…rBsonOutput.java Co-authored-by: Ross Lawley <ross.lawley@gmail.com>
…rBsonOutput.java Co-authored-by: Ross Lawley <ross.lawley@gmail.com>
…rBsonOutput.java Co-authored-by: Ross Lawley <ross.lawley@gmail.com>
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 ran ByteBufferBsonOutputTest
with Coverage, and noticed that ByteBufferBsonOutput#write(int absolutePosition, int value)
is no longer covered by test due to the optimizations that were introduced. This method should either be covered by tests or removed (it seems like it will never be called)
Here's one way to do it: https://github.com/jyemin/mongo-java-driver/pull/new/jeff-wip
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.
[Note] As @stIncMale suggested, lets put Evolving annotation here.
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.
Looking good - just javadocs and jeffs comment to address.
Summary
This PR improves BSON encoding by replacing byte manipulations and bound checks with ByteBuffer’s optimized methods (putInt, putLong, putDouble). These methods are optimized for bulk operations and often intrinsified by the JVM using efficient CPU opcodes, leading to reduced overhead and better performance.
Key Changes:
writeInt32(int absolutePosition, int value)
from 4 to 1 by preferring a single putInt call when capacity allows, minimizing overhead. Adds a fallback for edge cases (e.g., buffer boundaries) with O(1) buffer switches instead of repeated O(n) lookups.putInt(int)
,putInt(int, int)
,putDouble(double)
, andputLong(long)
toByteBuf
, implemented inByteBufNIO
andNettyByteBuf
, with no-op stubs inCompositeByteBuf
.ByteBufferBsonOutput
to: UseputInt
,putLong
, andputDouble
for single-call writes when capacity allows, reducing overhead.Performance analysis
To ensure accurate performance comparison and reduce noise, 11 versions (Comparison Versions) were aggregated and compared against a stable region of data around the Base Mainline Version. The percentage difference and z-score of the mean of the Comparison Versions were calculated relative to the Base Mainline Version’s stable region mean.
Perf analyzer results: Link
JAVA-5800