Can compiler's optimizer eliminate trivial heap allocation?

I have two logically equivalent functions that take a string and simply return it. This is a problem abstracted from a data processing library, so the result is returned via an output writable parameter (here &mut String for simplicity).

pub fn append(to: &mut String, a: &str) {
    to.push_str(a);
}

pub fn allocate_append(to: &mut String, a: &str) {
    to.push_str(&a.to_string());
}

Using https://godbolt.org/ (with -O compiler flag) i can see that the string allocation in the allocate_append is not being eliminated, so the function has one more memcpy call and also additional calls to __rust_alloc and __rust_dealloc.

Question:
under what circumstances can the compiler eliminate heap allocation?
if never, will it be possible in the future, or are there fundamental limitations preventing this?

Note:
I wrote a similar code C++ code and run it thru godbolt with gcc -O9. Same behavior.

I don't believe that rustc (the front/middle part of the Rust compiler) or LLVM (the backend) do this kind of analysis. If you repeat the call to to_string(), for example:

    to.push_str(&a.to_string().to_string().to_string());

then the compiler should produce multiple heap allocations.

In theory, this optimization could be done, but one could also argue that the extra complexity is unnecessary, and the onus should be on the developer to not make a redundant function call to to_string() when it's not needed.

You might want to ask this question on the Rust Internals forum:

Thank you hax10 for your response!

I agree, especially in this simplified case shown here.
For the redundant to_string() call, Clippy checker would be sufficient.

For context in my original case (not shown here) I have a function returning String which is then written to an output buffer, and String allocation not being optimized away. To avoid it I have need to pass an "out" parameter eg &Writer (which works as long as all callers are OK with such unusual return convention). Thus, I think being able to optimize-away allocation is has some practical applications.

You might want to ask this question on the Rust Internals forum:

thanks for the link!

I didn't find an answer there, so cross-posted ( Can compiler’s optimizer eliminate trivial heap allocation? - compiler - Rust Internals )

1 Like

You could try returning impl Display instead. The caller can the use the return value in a write! call, and no allocation is needed. It might complicate the implementation a bit tho.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.