Skip to content

Commit 582b0f8

Browse files
committed
Use a cached EOFException rather than constructing new.
Exception creation (or more correctly, stack trace generation) is not cheap on the JVM. By creating a new EOFException for every read EOF, we introduce a lot of overhead into processes that open many small files and read them to completion. The EOFExceptions we raise are also immediately caught and turned into appropriate Ruby errors or return values. In order to reduce the cost of EOF reads, I've introduced a single cached EOFException we throw for all EOF events. Commenting out its initialization in ChannelStream will return the original behavior, if necessary for debugging.
1 parent 629211b commit 582b0f8

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed
Binary file not shown.
Binary file not shown.

src/org/jruby/util/io/ChannelStream.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ public class ChannelStream implements Stream, Finalizable {
9090
private final static int BULK_READ_SIZE = 16 * 1024;
9191
private final static ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
9292

93+
/**
94+
* A cached EOFException. Since EOFException is only used by us internally,
95+
* we create a single instance to avoid stack trace generation. Comment out
96+
* the initialization of this field to cause a new one each time.
97+
*/
98+
private static EOFException eofException = new EOFException();
99+
93100
private volatile Ruby runtime;
94101
protected ModeFlags modes;
95102
protected boolean sync = false;
@@ -933,13 +940,21 @@ private int bufferedRead(ByteList dst, int number) throws IOException, BadDescri
933940

934941
if (bytesRead == 0 && number != 0) {
935942
if (eof) {
936-
throw new EOFException();
943+
throw newEOFException();
937944
}
938945
}
939946

940947
return bytesRead;
941948
}
942949

950+
private EOFException newEOFException() {
951+
if (eofException != null) {
952+
return eofException;
953+
} else {
954+
return new EOFException();
955+
}
956+
}
957+
943958
private int bufferedRead(ByteBuffer dst, boolean partial) throws IOException, BadDescriptorException {
944959
checkReadable();
945960
ensureRead();
@@ -1003,7 +1018,7 @@ private int bufferedRead(ByteBuffer dst, boolean partial) throws IOException, Ba
10031018
}
10041019

10051020
if (eof && bytesRead == 0 && dst.remaining() != 0) {
1006-
throw new EOFException();
1021+
throw newEOFException();
10071022
}
10081023

10091024
return bytesRead;

0 commit comments

Comments
 (0)