-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Summary
The lint single_char_pattern
suggest replacing a string with a char constant, but this actually results in significantly worse performance for wide Unicode characters in strip_prefix
.
In some sense this is a rust standard library issue, but clippy shouldn't suggest this as an improvement and say "Performing these methods using a char is faster than using a str." when the opposite is true.
This seems to be the case for strip_prefix
and strip_suffix
. For other methods like split
, char is always faster than str.
Simplest fix: remove strip_prefix
and strip_suffix
from the list of functions to check in this lint.
Lint Name
single_char_pattern
Reproducer
Here is a benchmark:
use criterion::{black_box, criterion_group, criterion_main, Criterion};
pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("strip_prefix str ascii", |b| b.iter(|| black_box("hello world").strip_prefix("h")));
c.bench_function("strip_prefix char ascii", |b| b.iter(|| black_box("hello world").strip_prefix('h')));
c.bench_function("strip_prefix str unicode", |b| b.iter(|| black_box("おはよう、世界").strip_prefix("お")));
c.bench_function("strip_prefix char unicode", |b| b.iter(|| black_box("おはよう、世界").strip_prefix('お')));
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
For which clippy reports:
warning: single-character string constant used as pattern
--> src\main.rs:4:101
|
4 | c.bench_function("strip_prefix str ascii", |b| b.iter(|| black_box("hello world").strip_prefix("h")));
| ^^^ help: try using a `char` instead: `'h'`
|
= note: `#[warn(clippy::single_char_pattern)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
warning: single-character string constant used as pattern
--> src\main.rs:6:97
|
6 | c.bench_function("strip_prefix str unicode", |b| b.iter(|| black_box("おはよう、世界").strip_prefix("お")));
| ^^^^ help: try using a `char` instead: `'お'`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
The documentation says "Performing these methods using a char is faster than using a str."
Benchmark output:
strip_prefix str ascii time: [4.3805 ns 4.4939 ns 4.6732 ns]
strip_prefix char ascii time: [4.2060 ns 4.2173 ns 4.2305 ns]
strip_prefix str unicode
time: [4.7124 ns 4.7187 ns 4.7270 ns]
strip_prefix char unicode
time: [11.643 ns 11.677 ns 11.715 ns]
The performance with a single character Unicode pattern is better with a string pattern than with a char pattern. So clippy shouldn't suggest this change.
Version
rustc 1.59.0-nightly (efec54529 2021-12-04)
binary: rustc
commit-hash: efec545293b9263be9edfb283a7aa66350b3acbf
commit-date: 2021-12-04
host: x86_64-pc-windows-msvc
release: 1.59.0-nightly
LLVM version: 13.0.0
Additional Labels
No response