It's really not, it's the way python works. Heap allocations are "fast" on modern CPUs that are too fast to measure for most stuff, but they're much (much) slower than the function call and code you're going to use to operate on whatever the thing it was you cloned.
Code that needs memory safety and can handle performance requirements like this has many options for source language, almost none of which require blog posts to "flatten the learning curve".
(And to repeat: it's much slower than a GC which doesn't have to make the clone at all. Writing Rust that is "Slower Than Java" is IMHO completely missing the point. Java is boring as dirt, but super easy!)
If the object had a stack-bounded lifetime, the borrow checker would have been able to prove the analysis though. The advice is to clone things it can't, which pretty much requires that it go into the general heap. I'm sure there are some interesting counterexamples, but the situation you're imagining seems kinda academic.
The fact something goes to heap doesn’t necessarily mean it needs more heap allocations. I’ve had it many times that I instantiated a new object on heap and had to pass cloned arguments to it (because it had to own them), yet they ended up as inline fields, so no additional allocations. Happens a lot with Rc / Arc.
Once more: if the compiler can see to inline the object or put it on the stack or replace it with a by-value/in-register copy, then the borrow checker wouldn't have puked to begin with. The advice is very clearly to make heap allocations as a way to evade borrow analysis. I don't see why that's controversial.
It's really not, it's the way python works. Heap allocations are "fast" on modern CPUs that are too fast to measure for most stuff, but they're much (much) slower than the function call and code you're going to use to operate on whatever the thing it was you cloned.
Code that needs memory safety and can handle performance requirements like this has many options for source language, almost none of which require blog posts to "flatten the learning curve".
(And to repeat: it's much slower than a GC which doesn't have to make the clone at all. Writing Rust that is "Slower Than Java" is IMHO completely missing the point. Java is boring as dirt, but super easy!)