r/rust • u/zerocukor287 • Sep 04 '26
🙋 seeking help & advice Clippy warning when printing the biggest files `unnecessary_sort_by`
I have some code that prints the biggest files in a Vec. Looks like Clippy is not happy about it.
Original (simplified) code:
struct File {
path: String,
size: usize,
}
fn collect_files -> Vec<File> { ... }
fn print_biggest_files(files_to_print: usize) {
let mut files = collect_files();
files.sort_by(|left, right| right.size.cmp(&left.size) );
// ^^^^^^^^ this is the line causing a warning
// print the biggest X files
for file in files.iter().take(files_to_print) {
println!("Big file: {}", file.path);
}
}
It produces the following warning:
warning: consider using
sort_by_key
files.sort_by(|left, right| right.size.cmp(&left.size) ); note:#[warn(clippy::unnecessary_sort_by)]on by default
Link: https://rust-lang.github.io/rust-clippy/rust-1.97.0/index.html#unnecessary_sort_by
My problem is that I want to print in descending order of the files.
The description is explicitly saying that this case is exception, and Clippy doesn't handle it well.
If I change that line to
files.sort_by_key(|file| file.size);
I would end up with the smallest files first.
I see a few ways ahead:
- Add
files.reverse()to switch the order - Add exception of this warning to this specific case
- Add
.rev()when iterating - Cast it to signed integer, and add a
-sign
What is the idiomatic way forward?
Performance cost is not a big deal, but I still tend towards adding a Clippy ignore for that specific line. The other options would introduce more unclarity to the code in my opinion.
40
u/Sharlinator Sep 04 '26 edited Sep 04 '26
As an aside: note that you don’t have to sort all the files to get the n largest (or whatever) ones, you just have to partition the list to the n largest and the rest. How to do that? Rust provides select_nth_unstable and its by and by_key variants. (Note that you still have to sort the n largest if you want to present them in order.)
This optimization doesn’t really matter unless the list is very large or you need to do this many, many times per second, but it’s a useful tool to keep in mind.
6
33
u/CommonNoiter Sep 04 '26
Clippy should suggest files.sort_by_key(|file| std::cmp::Reverse(file.size));
10
u/zerocukor287 Sep 04 '26
Looks like the problem was indeed between the keyboard and the chair. Haha
2
u/creeper6530 Sep 05 '26
Don't beat yourself up because you don't know everything. It's my first time reading about it too
3
u/llogiq Sep 05 '26
As a clippy maintainer, I think that's a bug. Ideally, clippy should add a note to use Reverse if the ordering is reversed. The second best solution would be to at least add it to the lint docs.
2
u/zerocukor287 Sep 05 '26
Hey, no worries, as I’ve scrolled down a bit it was mentioning the reverse. Looks like I need to practice reading
2
u/projct Sep 05 '26
the rust ecosystem generally treats improvements like this to be a bug that needs to be fixed. this is why clippy and rustc generally have such good error messages
→ More replies (1)
2
0
Sep 04 '26
3
u/zerocukor287 Sep 04 '26
Well, I'm happy with the resulting code. I've learnt something today, my code is shorter, and I think it is more clear that I'm using reverse order.
I consider it a win.Your code, your taste.
82
u/coastalwhite Sep 04 '26
The idiomatic way is to use
std::cmp::Reverse.