unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
To: Rich Felker <dalias@libc.org>
Cc: Szabolcs Nagy <Szabolcs.Nagy@arm.com>,
	'GNU C Library' <libc-alpha@sourceware.org>, nd <nd@arm.com>
Subject: Re: [PATCH v2] Improve performance of strstr
Date: Mon, 15 Apr 2019 18:02:27 +0000	[thread overview]
Message-ID: <AM6PR08MB5078A8FE8466F406C3BCD11B832B0@AM6PR08MB5078.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <20190415144051.GE23599@brightrain.aerifal.cx>

Hi Rich,

>> The O notation means O (256 N) is equivalent to O (N), ie. linear
>> performance in the worst case. And that is what matters for large inputs.
>
> I know what big O notation means. My point is that 256 is a
> sufficiently large number that, for practical purposes, the presence
> or absence of the M factor (whose value can be up to 256) in O(N) vs
> O(MN) is more significant than any small constant factors.

No, you can't gloss over one constant factor but emphasise another.
The constant factor is much smaller in my algorithm and actually gets
better (relatively) when you encounter bad cases. As a result worst
cases perform about the same even with needles of 256 characters.

>> The average runtime of my algorithm is actually sublinear. So in that
>> sense Two-Way performs pathologically bad.
>
> For strstr, it's never sublinear because it operates on
> null-terminated strings (but the linear term can have a very small
> constant because of fast incremental strnlen-like operation, if you
> want). 

strstr requires strnlen of course but the main algorithm is still sublinear.
As a result performance improves with larger needles and the relative
amount of time spent in strnlen increases. Asymptotically it ends up
as fast as strnlen.

> For memmem, of course it can be sublinear. The widely used
> variant of twoway (used in both glibc and musl) does the jump table
> that makes it sublinear (or for strstr, smaller linear-term
> coefficient) already. If you're this unaware of what the current code
> is doing, you shouldn't be trying to replace it with something naive
> but rather trying to understand it and if/how it can be improved.

Well if you've actually seen the existing code, you'd know that it does
not use a skip table for all common cases. And when it uses one, it
actually slows down the worst case by an order of magnitude.
As a result Two-Way performs absolutely abysmally both in common
cases as well as worst cases. It's almost as if people designed it to be
as bad as possible!

Eg. normalised performance from GLIBC bench-strstr test:

                                          basic_strstr    twoway_strstr   strstr(new)
Length 65536/ 16, alignment  1/11, found: 3.07            1.0             11.0

Yes, twoway_strstr is 3 times SLOWER than a trivial quadratic loop...

>> Yes, without a reproducible example I can't see what your issue is. You
>> can't make it go quadratic because it simply isn't.
>
> Obviously it's not unbounded because you have a (very large) bound on
> the size, 256. I can make it do a 256-byte strcmp for nearly every
> byte of the input haystack. Maybe because of vectorization on some
> targets that's only 16x slower than the current code rather than 256x
> slower, but it's still a lot slower.

No you can't. It's impossible to make it do a full 256 byte memcmp every
character. And bad cases are not bad because of the time spent comparing
strings - they are bad because of mispredicted branches. So it's not possible
to compare bad cases without benchmarking actual examples on modern
CPUs.

Wilco

  reply	other threads:[~2019-04-15 18:02 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-31 21:01 [PATCH v2] Improve performance of strstr Wilco Dijkstra
2018-12-31 21:24 ` Rich Felker
2019-01-02 13:40   ` Wilco Dijkstra
2019-02-01 15:40 ` Wilco Dijkstra
2019-03-06 16:55   ` Wilco Dijkstra
2019-03-18 17:17     ` Wilco Dijkstra
2019-04-12 15:50       ` Wilco Dijkstra
2019-04-12 16:19         ` Szabolcs Nagy
2019-04-12 16:49           ` Wilco Dijkstra
2019-04-12 17:16             ` Rich Felker
2019-04-15 10:24               ` Wilco Dijkstra
2019-04-15 14:40                 ` Rich Felker
2019-04-15 18:02                   ` Wilco Dijkstra [this message]
2019-04-15 20:15                     ` Zack Weinberg
2019-04-16  0:13                       ` Rich Felker
2019-04-16 16:40                       ` Szabolcs Nagy
2019-04-16 17:01                         ` Szabolcs Nagy
2019-04-16 18:07                           ` Szabolcs Nagy
2019-04-16 20:56                             ` Rich Felker
2019-04-17 14:24                               ` Szabolcs Nagy
2019-04-17 15:10                                 ` Rich Felker
2019-04-18 13:51                                 ` Wilco Dijkstra
2019-04-18 15:20                                   ` Rich Felker
2019-04-18 16:16                                     ` Szabolcs Nagy
2019-04-18 16:37                                       ` Wilco Dijkstra
2019-04-18 17:02                                         ` Rich Felker
2019-04-16 22:52                             ` Wilco Dijkstra
2019-04-16 23:40                               ` Rich Felker
2019-04-16 23:49                                 ` Wilco Dijkstra
2019-04-17  0:37                                   ` Rich Felker
2019-04-17  0:54                                     ` Wilco Dijkstra
2019-04-17  2:22                                       ` Rich Felker
2019-04-17 15:06                               ` Wilco Dijkstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/libc/involved.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AM6PR08MB5078A8FE8466F406C3BCD11B832B0@AM6PR08MB5078.eurprd08.prod.outlook.com \
    --to=wilco.dijkstra@arm.com \
    --cc=Szabolcs.Nagy@arm.com \
    --cc=dalias@libc.org \
    --cc=libc-alpha@sourceware.org \
    --cc=nd@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).