From 0beb4a102870eedf3720c7214b707d60e6e7738b Mon Sep 17 00:00:00 2001 From: William Burns Date: Fri, 4 Oct 2024 08:29:41 -0700 Subject: [PATCH] IPROTO-394 Optimize TagWriterImpl#writeString for ASCII only Strings --- .../protostream/impl/TagWriterImpl.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/infinispan/protostream/impl/TagWriterImpl.java b/core/src/main/java/org/infinispan/protostream/impl/TagWriterImpl.java index ba4baf4b..9e36e217 100644 --- a/core/src/main/java/org/infinispan/protostream/impl/TagWriterImpl.java +++ b/core/src/main/java/org/infinispan/protostream/impl/TagWriterImpl.java @@ -131,13 +131,30 @@ public void writeVarint64(long value) throws IOException { encoder.writeVarint64(value); } + public static boolean onlyAscii(String ba, int off, int len) { + int limit = off + len; + for (int i = off; i < limit; i++) { + if (ba.charAt(i) > 127) { + return false; + } + } + return true; + } + @Override - public void writeString(int number, String value) throws IOException { - // TODO [anistor] This is expensive! What can we do to make it more efficient? + public void writeString(int number, String s) throws IOException { // Also, when just count bytes for message size we do a useless first conversion, and another one will follow later. + if (onlyAscii(s, 0, s.length())) { + encoder.writeLengthDelimitedField(number, s.length()); + for (int i = 0; i < s.length(); ++i) { + encoder.writeByte((byte) s.charAt(i)); + } + return; + } + // Charset.encode is not able to encode directly into our own buffers! - byte[] utf8buffer = value.getBytes(StandardCharsets.UTF_8); + byte[] utf8buffer = s.getBytes(StandardCharsets.UTF_8); encoder.writeLengthDelimitedField(number, utf8buffer.length); encoder.writeBytes(utf8buffer, 0, utf8buffer.length);