Skip to content
This repository was archived by the owner on Dec 20, 2022. It is now read-only.

Commit 5a81503

Browse files
committed
Staticly initialize DirectByteBuffer constructor
Java reflection is quite expensive (https://docs.oracle.com/javase/tutorial/reflect/index.html): "Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications." In critical path we call getByteBuffer quite frequently: https://user-images.githubusercontent.com/1121987/47508402-bcce9680-d87c-11e8-99d2-7b55677e4d3e.png So we could statically initialize ByteBuffer constructor reflection, and only instantiate it based on the arguments. Change-Id: Ibca8ddbd67c4239a6e462a453669b7519c89afc8
1 parent c340eae commit 5a81503

File tree

3 files changed

+15
-49
lines changed

3 files changed

+15
-49
lines changed

src/main/java/org/apache/spark/shuffle/rdma/RdmaBuffer.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,18 @@ class RdmaBuffer {
4040
private final MemoryBlock block;
4141
private AtomicInteger refCount;
4242

43-
public static final UnsafeMemoryAllocator unsafeAlloc = new UnsafeMemoryAllocator();
43+
static final UnsafeMemoryAllocator unsafeAlloc = new UnsafeMemoryAllocator();
44+
public static final Constructor<?> directBufferConstructor;
45+
46+
static {
47+
try {
48+
Class<?> classDirectByteBuffer = Class.forName("java.nio.DirectByteBuffer");
49+
directBufferConstructor = classDirectByteBuffer.getDeclaredConstructor(long.class, int.class);
50+
directBufferConstructor.setAccessible(true);
51+
} catch (Exception e) {
52+
throw new RuntimeException("java.nio.DirectByteBuffer class not found");
53+
}
54+
}
4455

4556
RdmaBuffer(IbvPd ibvPd, int length) throws IOException {
4657
block = unsafeAlloc.allocate((long)length);
@@ -126,25 +137,10 @@ private void unregister() {
126137
}
127138

128139
ByteBuffer getByteBuffer() throws IOException {
129-
Class<?> classDirectByteBuffer;
130-
try {
131-
classDirectByteBuffer = Class.forName("java.nio.DirectByteBuffer");
132-
} catch (ClassNotFoundException e) {
133-
throw new IOException("java.nio.DirectByteBuffer class not found");
134-
}
135-
Constructor<?> constructor;
136-
try {
137-
constructor = classDirectByteBuffer.getDeclaredConstructor(long.class, int.class);
138-
} catch (NoSuchMethodException e) {
139-
throw new IOException("java.nio.DirectByteBuffer constructor not found");
140-
}
141-
constructor.setAccessible(true);
142-
ByteBuffer byteBuffer;
143140
try {
144-
byteBuffer = (ByteBuffer)constructor.newInstance(getAddress(), getLength());
141+
return (ByteBuffer)directBufferConstructor.newInstance(getAddress(), getLength());
145142
} catch (Exception e) {
146143
throw new IOException("java.nio.DirectByteBuffer exception: " + e.toString());
147144
}
148-
return byteBuffer;
149145
}
150146
}

src/main/java/org/apache/spark/shuffle/rdma/RdmaMappedFile.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -200,30 +200,14 @@ public void dispose() throws IOException, InvocationTargetException, IllegalAcce
200200
}
201201

202202
private ByteBuffer getByteBuffer(long address, int length) throws IOException {
203-
Class<?> classDirectByteBuffer;
204203
try {
205-
classDirectByteBuffer = Class.forName("java.nio.DirectByteBuffer");
206-
} catch (ClassNotFoundException e) {
207-
throw new IOException("java.nio.DirectByteBuffer class not found");
208-
}
209-
Constructor<?> constructor;
210-
try {
211-
constructor = classDirectByteBuffer.getDeclaredConstructor(long.class, int.class);
212-
} catch (NoSuchMethodException e) {
213-
throw new IOException("java.nio.DirectByteBuffer constructor not found");
214-
}
215-
constructor.setAccessible(true);
216-
ByteBuffer byteBuffer;
217-
try {
218-
byteBuffer = (ByteBuffer)constructor.newInstance(address, length);
204+
return (ByteBuffer)RdmaBuffer.directBufferConstructor.newInstance(address, length);
219205
} catch (InvocationTargetException ex) {
220206
throw new IOException("java.nio.DirectByteBuffer: " +
221207
"InvocationTargetException: " + ex.getTargetException());
222208
} catch (Exception e) {
223209
throw new IOException("java.nio.DirectByteBuffer exception: " + e.toString());
224210
}
225-
226-
return byteBuffer;
227211
}
228212

229213
public ByteBuffer getByteBufferForPartition(int partitionId) throws IOException {

src/main/java/org/apache/spark/shuffle/rdma/RdmaRegisteredBuffer.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.apache.spark.shuffle.rdma;
1919

2020
import java.io.IOException;
21-
import java.lang.reflect.Constructor;
2221
import java.nio.ByteBuffer;
2322
import java.util.concurrent.atomic.AtomicInteger;
2423

@@ -75,22 +74,9 @@ ByteBuffer getByteBuffer(int length) throws IOException {
7574
throw new IllegalArgumentException("Exceeded Registered Length!");
7675
}
7776

78-
Class<?> classDirectByteBuffer;
79-
try {
80-
classDirectByteBuffer = Class.forName("java.nio.DirectByteBuffer");
81-
} catch (ClassNotFoundException e) {
82-
throw new IOException("java.nio.DirectByteBuffer class not found");
83-
}
84-
Constructor<?> constructor;
85-
try {
86-
constructor = classDirectByteBuffer.getDeclaredConstructor(long.class, int.class);
87-
} catch (NoSuchMethodException e) {
88-
throw new IOException("java.nio.DirectByteBuffer constructor not found");
89-
}
90-
constructor.setAccessible(true);
9177
ByteBuffer byteBuffer;
9278
try {
93-
byteBuffer = (ByteBuffer)constructor.newInstance(
79+
byteBuffer = (ByteBuffer)RdmaBuffer.directBufferConstructor.newInstance(
9480
getRegisteredAddress() + (long)blockOffset, length);
9581
blockOffset += length;
9682
} catch (Exception e) {

0 commit comments

Comments
 (0)