Files
Michiel van Slobbe b904884b94 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.
2026-10-10 21:50:10 +09:00

39 lines
1.3 KiB
Bash
Executable File

#!/bin/sh -x
. "${0%/*}/setup" "$@"
# Reading jq file does not corrupt multi-byte characters -- #1311
for l in 1 2 3 4; do
$VALGRIND $Q $JQ -rn "[(range($l) | 48), (range(3000) | 128515)] | implode |
\"\\(tojson) | explode | unique == [48, 128515]\"" > $d/input
if ! $VALGRIND $Q $JQ -nef $d/input > /dev/null; then
echo "Reading jq file corrupted multi-byte characters"
exit 1
fi
done
# Slurping raw input does not corrupt multi-byte characters -- #3389
for l in 1 2 3 4; do
$VALGRIND $Q $JQ -jn "[(range($l) | 48), (range(3000) | 128515)] | implode" > $d/input
if ! $VALGRIND $Q $JQ -Rse 'explode | unique == [48, 128515]' $d/input > /dev/null; then
echo "Slurping raw input corrupted multi-byte characters"
exit 1
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