Skip to content

Commit

Permalink
Speedup RecyclerBytesStreamOutput.writeString
Browse files Browse the repository at this point in the history
This method is quite hot in some use-cases because it's used by
most string writing to transport messages. Overriding teh default
implementation for cases where we can write straight to the
page instead of going through an intermediary buffer speeds up
the method by more than 2x, saving lots of cycles, especially
on transport threads.
  • Loading branch information
original-brownbear committed Sep 20, 2024
1 parent 7c65ad5 commit e7a3703
Showing 1 changed file with 29 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,35 @@ public void writeWithSizePrefix(Writeable writeable) throws IOException {
}
}

@Override
public void writeString(String str) throws IOException {
final int currentPageOffset = this.currentPageOffset;
final int charCount = str.length();
// maximum serialized length is 3 bytes per char + 5 bytes for the longest possible vint
if (charCount * 3 + 5 > (pageSize - currentPageOffset)) {
super.writeString(str);
return;
}
BytesRef currentPage = pages.get(pageIndex).v();
int off = currentPage.offset + currentPageOffset;
byte[] buffer = currentPage.bytes;
int offset = off + putVInt(buffer, charCount, off);
for (int i = 0; i < charCount; i++) {
final int c = str.charAt(i);
if (c <= 0x007F) {
buffer[offset++] = ((byte) c);
} else if (c > 0x07FF) {
buffer[offset++] = ((byte) (0xE0 | c >> 12 & 0x0F));
buffer[offset++] = ((byte) (0x80 | c >> 6 & 0x3F));
buffer[offset++] = ((byte) (0x80 | c >> 0 & 0x3F));
} else {
buffer[offset++] = ((byte) (0xC0 | c >> 6 & 0x1F));
buffer[offset++] = ((byte) (0x80 | c >> 0 & 0x3F));
}
}
this.currentPageOffset = offset - currentPage.offset;
}

@Override
public void flush() {
// nothing to do
Expand Down

0 comments on commit e7a3703

Please sign in to comment.