Hi Willy,

On Mon, Oct 26, 2026 at 12:51:24PM +0100, Willy Tarreau wrote:
> Nice, however I'm having a question here:
> Did you try with a byte-by-byte approach instead of memchr() for
> this one ? memchr() tends to be heavy for short strings since it
> is usually fast thanks to vectorization, but parameter names are
> almost always super short (1 or 2 chars), so I suspect you could
> observe even further gainst using iststop() or something like this,
> like was done before but admittedly not at an optimal place.

I hadn't, and the v1 workload only had 6 character names, which is
the case that flatters memchr(). I measured both now on the same box,
20 kB query strings, five 120 s runs per point for the query cases:

  427 params, 6 byte names (p00000=...)    1188.5 -> 1180.4 us  -0.7%
  467 params, 1-2 byte names (a=...zz=)    1163.0 -> 1151.4 us  -1.0%
  8 byte path                               344.6 ->  345.2 us  (noise)

You were right: the byte loop wins in both query cases, a bit more on
the short names, and every one of the five runs with iststop() was
faster than every run with memchr() (run-to-run spread is about 4 to
5 us), so it is small but not noise. v2 uses iststop(). I think the
reason it does not show more is that the lookup is a small part of
the work: qsort() still makes about n*log2(n) comparisons, roughly
4000 for 467 parameters, against 467 lookups, and the whole string is
copied once more after that, so whatever the lookup costs is diluted
about ten to one.

Thanks,
Youngkwang


Reply via email to