Doesn't recognise open-coded memchr() (like in std::count(char *, char *, char)), so produces code 40% slower than if it used memchr()
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
With a
```cpp
char buf[64 * 1024];
ssize_t rd = read(fd, buf, sizeof(buf));
```
preamble
```cpp
acc += std::count(buf, buf + rd, '\n');
```
is 40-50% slower than
```cpp
auto newitr = buf;
auto len = rd;
char * itr;
// This is still suboptimal: a while(itr != end && *itr == '\n') ++acc; will be better if the data has consecutive needles but this is covered by std::count
while(len && (newitr = static_cast(std::memchr(itr = newitr, '\n', len)))) {
++acc.newlines;
++newitr;
len -= newitr - itr;
}
```
on clang trunk 1:21.0-61~exp1+0~20250421201207.11~1.gbp5a3b95.
Full program and dataset at , where I observe, for a 184M file with 290957 lines of line-delimited JSON, std::count takes ~140ms and memchr takes ~67ms on E5645.
The same happens on libc++.
`perf record` shows 62% in the lambda for std::count and 25% in __memchr_sse2 for memchr.
LLVM should understand that for a `Byte * beg, end`, `while(beg != end && *beg == needle) ++beg;` is an open-coding of memchr() and reify that to memchr.
Contributor guide
Assessment
This issue has not been assessed yet.