Whereas in Rust you know that it's probably possible to use a &str there instead of a String. If you just bang on it a little longer, you can make it just a bit more optimal. The clone()s and the Vec::new()s are all explicit, making them feel heavier than those other languages, when in reality they're still quite a bit lighter.
You usually don't have to optimize them out! Your code will probably be faster than Java even with a bunch of clones, etc! But there's this temptation that's really hard for programmers to resist, to sink hours and hours into making things just slightly more optimal given the opportunity. You have to consciously talk yourself out of that if you want to be productive.
That's… not exactly true. `Vec::new` is completely free so that's a different debate, but much as in C++ or C allocations in Rust are much more expensive than in managed languages:
1. system allocators genuinely suck, all of them, though some more than others (iirc macos' is especially bad)
2. managed languages can much more easily specialised allocation strategies (freelists, bump allocators, type-custom allocation strategies), this is either difficult / impossible (no custom allocators) or way more painful (manually pass custom allocators in) in Rust
As a result, allocations in Rust are really tremendously slow by default, it's not too rare to see questions about Rust programs which are slower than managed equivalents, in release mode. Because the rust program is allocation heavy (relatively), it might have 10% the allocations of the non-rust program but the allocations are 100 times more expensive.
Edit: I do know that languages where strings are immutable use that fact to do lots of optimization (automatically sharing "copied" strings and just cloning reference-counters, for example), but you can accomplish some of this in Rust too with Rc<> or even persistent data structures if you really want to. And of course there are cases where it's more efficient to actually mutate a string, which these languages can't do. But it sounds like you're talking about something else?
That's 100% correct but there's one problem: how do you write down your future improvement opportunities?
Skip 2 optimizations here, 3 optimizations there and after 30 PRs you can easily have notes spanning 100 bullet points on what to optimize one day in the future Soon™.
I am still not at what I'd call an expert level in Rust -- and the skill ceiling is quite high -- so maybe with time I'd start to automatically spot these optimization opportunities?
But before I am at that level I'd prefer to either keep hugely long notes or, ideally, have a tool recommend optimizations to me.
The better tool is to profile the code, then optimize hotspots. There's a Rust Performance Book with a list of profilers known to work with Rust programs[1]. Rustc does support Profile Guided Optimization[2] which is often pretty good at speeding up the output even without any code changes.
[1] https://nnethercote.github.io/perf-book/profiling.html [2] https://doc.rust-lang.org/rustc/profile-guided-optimization....