@ 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 tests/utf8test. All files

tests/utf8test

@@ -21,4 +21,18 @@ for l in 1 2 3 4; do   fi done +# --ascii-output escapes non-ASCII characters on both sides of runs of+# bytes that need no escaping+$VALGRIND $Q $JQ -cn '[range(18) as $i | ("é", "😀", "\u007f") as $c |+  "abcdefghijklmnopq"[:$i] + $c + "abcdefghijklmnopq"[$i:]]' > $d/input+$VALGRIND $Q $JQ -ac . $d/input > $d/out+if LC_ALL=C grep -q '[^ -~]' $d/out; then+  echo "--ascii-output printed a non-ASCII byte"+  exit 1+fi+if ! $VALGRIND $Q $JQ -e --slurpfile a $d/input '. == $a[0]' $d/out > /dev/null; then+  echo "--ascii-output changed a string"+  exit 1+fi+ exit 0