Rust sort_unstable_by with more complex closure unexpectedly shrunk binary

Thing I stumbled upon:

I added boolean argument and if statement inside sort_unstable_by closure:

``` //from

|&a, &b| compare(a, b)

//to

|&a, &b| if is_reverse { compare(b, a) } else { compare(a, b) } ```

I expected binary to grow slightly, but actually it became ca 1KB smaller.

I dug into with bloaty and found that the reason is: quicksort fn became 980 bytes smaller.

Still not sure why. Inlining looks same, quicksort just has fewer instructions.

target: arm-unknown-linux-gnueabihf

details: https:// pastebin.com/qJdTw49n

commit: https://github.com/tracyspacy/fli/commit/a87a98be77cc1972a53e6399716a227d1135e76b

5 points | by tracyspacy 6 hours ago

1 comments

  • derdi 2 hours ago
    I didn't look at the details you posted, but as a compiler engineer, the general statement doesn't surprise me. More complex control flow can block optimizations. Many compiler optimizations involve duplicating code in some way (loop unrolling, for example). Hence, more complex control flow can block optimizations that would increase code size.
    • tracyspacy 24 minutes ago
      I don't think the loop unrolling plays a big role here, I guess it was more an example. While post body contains control flow, it can be simple arithmetic operation instead and it will lead to the similar result, so not the control flow itself causing this. But yeah, I also feel, that more complex closure blocks some optimizations here, thus quicksort having less instructions. I suspect that complex closure was outlined to a separate fn, and not copied to quicksort anymore.