We implement a few optimizations to make the decoder faster and allocate less:
avoid allocating the escape buffer up front: this avoids and allocation when there's nothing to unescape
use strings.IndexByte as a prequel to strings.Count in escaper.escapedLen and keep track of the
earliest found replacement index.
keep a bitwise or of the bytes that we've seen when taking a token, and invoke utf8.Valid only
when there's a byte with the top bit set, saving a call to utf8.Valid in the common case at the expense
of one pipelinable instruction.
We implement a few optimizations to make the decoder faster and allocate less:
strings.IndexByte
as a prequel tostrings.Count
inescaper.escapedLen
and keep track of the earliest found replacement index.utf8.Valid
only when there's a byte with the top bit set, saving a call toutf8.Valid
in the common case at the expense of one pipelinable instruction.Benchmark results show some nice improvements:
Thanks to @stuartcarnie for some of the ideas here.