This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fury.git
The following commit(s) were added to refs/heads/main by this push:
new 676c5742 perf(java): Improve performance by using System.arraycopy to
copy between byte arrays (#2101)
676c5742 is described below
commit 676c5742b94ec30137cf282b7ebfd69186d9f8b6
Author: Seppe Volkaerts <[email protected]>
AuthorDate: Sun Mar 16 05:49:30 2025 +0100
perf(java): Improve performance by using System.arraycopy to copy between
byte arrays (#2101)
## What does this PR do?
Try to use `System.arraycopy` when copying between byte arrays. This
significantly increases performance, in our use case serialization is
twice as fast (serializing/deserializing 1M complex strucutures using
(de)serializeJavaObject in parallel). When using Platform.copyMemory,
the JDK is doing a lot of type checking to see if it's a byte array,
causing a visible slowdown. `Unsafe.memoryCopy` implementation was
changed in Java 9 from a native method to a method calling the internal
unsafe method containing the reflection checks.
There are a few places where System.arraycopy is already used, referring
to it being faster on certain JDK implementations. Tested our use case
on a macbook with arm64 cpu against zulu 21 and open-jdk 23.

## Does this PR introduce any user-facing change?
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
I tried to reproduce the performance impact through one on existing
benchmarks `UserTypeSerializeSuite.fury_serialize`, however I didn't see
a difference here.
Signed-off-by: Seppe Volkaerts <[email protected]>
---
.../java/org/apache/fury/memory/MemoryBuffer.java | 56 +++++++++++++---------
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git
a/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
b/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
index d5003e36..e9f4ba11 100644
--- a/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
+++ b/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
@@ -313,17 +313,23 @@ public final class MemoryBuffer {
}
public void get(int index, byte[] dst, int offset, int length) {
- final long pos = address + index;
- if ((index
- | offset
- | length
- | (offset + length)
- | (dst.length - (offset + length))
- | addressLimit - length - pos)
- < 0) {
- throwOOBException();
+ final byte[] heapMemory = this.heapMemory;
+ if (heapMemory != null) {
+ // System.arraycopy faster for some jdk than Unsafe.
+ System.arraycopy(heapMemory, heapOffset + index, dst, offset, length);
+ } else {
+ final long pos = address + index;
+ if ((index
+ | offset
+ | length
+ | (offset + length)
+ | (dst.length - (offset + length))
+ | addressLimit - length - pos)
+ < 0) {
+ throwOOBException();
+ }
+ Platform.copyMemory(null, pos, dst, Platform.BYTE_ARRAY_OFFSET + offset,
length);
}
- Platform.copyMemory(heapMemory, pos, dst, Platform.BYTE_ARRAY_OFFSET +
offset, length);
}
public void get(int offset, ByteBuffer target, int numBytes) {
@@ -378,19 +384,25 @@ public final class MemoryBuffer {
}
public void put(int index, byte[] src, int offset, int length) {
- final long pos = address + index;
- // check the byte array offset and length
- if ((index
- | offset
- | length
- | (offset + length)
- | (src.length - (offset + length))
- | addressLimit - length - pos)
- < 0) {
- throwOOBException();
+ final byte[] heapMemory = this.heapMemory;
+ if (heapMemory != null) {
+ // System.arraycopy faster for some jdk than Unsafe.
+ System.arraycopy(src, offset, heapMemory, heapOffset + index, length);
+ } else {
+ final long pos = address + index;
+ // check the byte array offset and length
+ if ((index
+ | offset
+ | length
+ | (offset + length)
+ | (src.length - (offset + length))
+ | addressLimit - length - pos)
+ < 0) {
+ throwOOBException();
+ }
+ final long arrayAddress = Platform.BYTE_ARRAY_OFFSET + offset;
+ Platform.copyMemory(src, arrayAddress, null, pos, length);
}
- final long arrayAddress = Platform.BYTE_ARRAY_OFFSET + offset;
- Platform.copyMemory(src, arrayAddress, heapMemory, pos, length);
}
public byte getByte(int index) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]