Issue #2849
It turns out that the lion's share of the time was consumed
by byte-by-byte operations. There were two factors:
1. Calling panic in a function somehow makes it more expensive.
2. Calling a function through an interface also adds up.
This PR makes spot improvements to address two cases:
1. The tokenizer was calling bytes.Buffer.WriteByte for every byte
of the input query.
2. The EncodeSQL function in sqltypes.Value was calling
a wrapper (that had a panic), which in turn called
buffer.WriteByte.
I've now written a bytes2.Buffer package that implements a subset
of bytes.Buffer, but more efficiently.
Resulting improvements:
VTGate New:
BenchmarkWithNormalizer-4 300 5694660 ns/op
VTGate Old:
BenchmarkWithNormalizer-4 100 10927765 ns/op
VTTablet New:
BenchmarkExecuteVarBinary-4 300 4751125 ns/op
VTTablet Old:
BenchmarkExecuteVarBinary-4 100 14888528 ns/op
These numbers can further be improved as mentioned in the issue.
But the work to get to the next level is more involved.