Skip to content

Commit

Permalink
More tiny tweaks to reduce overhead of generateString
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Jan 16, 2025
1 parent 7f9b6a3 commit 70aadd0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
4 changes: 3 additions & 1 deletion java/src/json/ext/ByteListTranscoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,11 @@ protected void quoteStart() {
* until the character before it.
*/
protected void quoteStop(int endPos) throws IOException {
int quoteStart = this.quoteStart;
if (quoteStart != -1) {
ByteList src = this.src;
append(src.unsafeBytes(), src.begin() + quoteStart, endPos - quoteStart);
quoteStart = -1;
this.quoteStart = -1;
}
}

Expand Down
23 changes: 16 additions & 7 deletions java/src/json/ext/StringEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ final class StringEncoder extends ByteListTranscoder {
//First byte of a 4+ byte code point
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9,
};

private static final byte[] BACKSLASH_U2028 = "\\u2028".getBytes(StandardCharsets.US_ASCII);
private static final byte[] BACKSLASH_U2029 = "\\u2029".getBytes(StandardCharsets.US_ASCII);

private final boolean asciiOnly, scriptSafe;
private final byte[] escapeTable;

OutputStream out;

Expand All @@ -137,6 +139,11 @@ final class StringEncoder extends ByteListTranscoder {
StringEncoder(boolean asciiOnly, boolean scriptSafe) {
this.asciiOnly = asciiOnly;
this.scriptSafe = scriptSafe;
if (asciiOnly) {
escapeTable = scriptSafe ? SCRIPT_SAFE_ESCAPE_TABLE : ASCII_ONLY_ESCAPE_TABLE;
} else {
escapeTable = scriptSafe ? SCRIPT_SAFE_ESCAPE_TABLE : ESCAPE_TABLE;
}
}

// C: generate_json_string
Expand All @@ -151,9 +158,9 @@ void generate(ThreadContext context, RubyString object, OutputStream buffer) thr
case StringSupport.CR_7BIT:
case StringSupport.CR_VALID:
if (asciiOnly) {
encodeASCII(byteList, scriptSafe ? SCRIPT_SAFE_ESCAPE_TABLE : ASCII_ONLY_ESCAPE_TABLE);
encodeASCII(byteList);
} else {
encode(byteList, scriptSafe ? SCRIPT_SAFE_ESCAPE_TABLE : ESCAPE_TABLE);
encode(byteList);
}
break;
default:
Expand Down Expand Up @@ -201,20 +208,21 @@ private static RubyString tryWeirdEncodings(ThreadContext context, RubyString st
}

// C: convert_UTF8_to_JSON
void encode(ByteList src, byte[] escape_table) throws IOException {
void encode(ByteList src) throws IOException {
byte[] hexdig = HEX;
byte[] scratch = aux;
byte[] escapeTable = this.escapeTable;

byte[] ptrBytes = src.unsafeBytes();
int ptr = src.begin();
int len = src.realSize();

int beg = 0;
int pos = 0;

while (pos < len) {
int ch = Byte.toUnsignedInt(ptrBytes[ptr + pos]);
int ch_len = escape_table[ch];
int ch_len = escapeTable[ch];
/* JSON encoding */

if (ch_len > 0) {
Expand Down Expand Up @@ -278,9 +286,10 @@ private int flushPos(int pos, int beg, byte[] ptrBytes, int ptr, int size) throw
}

// C: convert_UTF8_to_ASCII_only_JSON
void encodeASCII(ByteList src, byte[] escape_table) throws IOException {
void encodeASCII(ByteList src) throws IOException {
byte[] hexdig = HEX;
byte[] scratch = aux;
byte[] escapeTable = this.escapeTable;

byte[] ptrBytes = src.unsafeBytes();
int ptr = src.begin();
Expand All @@ -291,7 +300,7 @@ void encodeASCII(ByteList src, byte[] escape_table) throws IOException {

while (pos < len) {
int ch = Byte.toUnsignedInt(ptrBytes[ptr + pos]);
int ch_len = escape_table[ch];
int ch_len = escapeTable[ch];

if (ch_len != 0) {
switch (ch_len) {
Expand Down

0 comments on commit 70aadd0

Please sign in to comment.