@ 261102.1

261010.3 · b904884b94ca48e025a12697ab172711e6c134d8

Improve performance of string output (#3643)

Printing a string wrote each character with a separate call, one fwrite() per character, or one jv_string_append_buf() for tojson and tostring, which made output of string-heavy data slow.

Scan ahead for the next byte that needs escaping and write the run of bytes before it with a single call, without changing the output. Printing strings is now significantly faster, most of all for long strings with few characters to escape, and the same applies to tojson and tostring. With --ascii-output, text that is almost all non-ASCII is about the same speed, since nearly every byte is escaped anyway.

reading declarations

Changes to src/jv_print.c. All files

src/jv_print.c

@@ -126,7 +126,18 @@ static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S, int T) {   int c = 0;   char buf[32];   put_char('"', F, S, T);-  while ((i = jvp_utf8_next((cstart = i), end, &c))) {+  while (i < end) {+    // Write each run of bytes that need no escaping with a single call.+    for (cstart = i; cstart < end; cstart++) {+      unsigned char b = *cstart;+      if (b < 0x20 || b == '"' || b == '\\' || b == 0x7F || (ascii_only && b >= 0x80))+        break;+    }+    if (cstart > i)+      put_buf(i, cstart - i, F, S, T);+    if (cstart == end)+      break;+    i = jvp_utf8_next(cstart, end, &c);     assert(c != -1);     int unicode_escape = 0;     if (0x20 <= c && c <= 0x7E) {