Can you put something like mold or env mold for better portability?
If not, I guess it’s not so bad to edit and do git update-index --assume-unchanged .cargo/config.toml but it’s a bit hacky since any further changes also get ignored.
With all the respect to the author and his wild experiments, that title does not match the linker-only focus of the content.
So not only the post ended up with two (IMHO) bad recommendations (disabling debug info, building non-relocatable binaries with musl). But it also didn’t mention other important factors like codegen-unitsand codegen-backend. Since you know, code generation is the other big contributor to the cycle time (the primary contributor even, in many cases). There is also other relevant options like lto and opt-level.
Let’s assume that opt-level shouldn’t be changed from defaults for no good reason.
With codegen-units, it’s not the default that is the problem, but the fact that some projects set it to 1 (for performance optimization reasons), but without adding a separate profile for development release builds (let’s call it release-dev).
Same goes for lto, where you can have it set to “full” in your optimized profile, and completely “off” in release-dev.
And finally, with codegen-backend, you can enjoy what is probably the biggest speed up in the cycle by using cranelift in your release-dev profile.
And of course you are not limited to just two release profiles. I usually use 3-4 myself. Profile inheritance makes this easy.
And finally, you can set/not set some of those selectively for your dependencies. For example, not using cranelift for dependencies can render the runtime performance delta negligible in some projects.
Using the parallel rustc front-end might become an interesting option too, but it’s not ready yet.
FizzyOrange@programming.dev
on 16 Nov 08:08
collapse
I think you’re being way too harsh.
His recommendations to disable debug info and PIC are not “bad”. He isn’t suggesting that should be the default. He actually only suggested that split debug info should be made the default on Linux which is a sensible suggestion.
There are gazillions of other posts talking about codegen-units, cranelift and so on. I don’t think we need a repeat (though he could have linked to them).
The focus on linking was because this post is introducing his liker project.
FizzyOrange@programming.dev
on 16 Nov 09:22
collapse
Ok that was maybe a bit unfair!
KillTheMule@programming.dev
on 15 Nov 07:03
nextcollapse
Huh, I did not know that you can speed up builds by stripping debug info, need to try that out :)
voklen@programming.dev
on 15 Nov 10:46
nextcollapse
For me the biggest speedup in my workflow was not through actually cutting down on the build time but rather using cargo watch. With cargo watch -x run, it automatically rebuilds and runs on any change so by the time I switch to the terminal it’s almost completely ready.
tengkuizdihar@programming.dev
on 16 Nov 05:14
collapse
I can imagine this to tank my PC performance, especially on large projects lol
onlinepersona@programming.dev
on 16 Nov 07:23
collapse
If you’re like many developers and you generally use println for debugging and rarely or never use an actual debugger, then this is wasted time.
I weep for the time lost on debugging with println. Good grief. It’s like having access to a time stopping ability and going “nah, I like trying to add a marker and tracing footsteps”.
Yes, for multi threaded workloads there aren’t many options, but most are single threaded and eschewing a debugger is bonkers to me.
And it’s needless to say that dbg!() also exists, which is better than manual printing for quick debugging.
So there exists a range of options setting between simple printing, and having to resort to using gdb/lldb (possibly with rr).
But yes, skipping debugging symbols was a bad suggestion.
kahnclusions@programming.dev
on 17 Nov 02:59
nextcollapse
This is always one of the first things I setup on a project and teach or encourage my teams to do… I’m always surprised how many devs would rather use print statements all the time (not just in Rust, but especially JS/TS) when it only takes like 5 minutes to configure the debugger. Maybe 10 minutes if you need to search how to open the debugging port in Chrome/FF.
I have to admit I still readily reach for dbg! to narrow down where the problem is happening (instead of endlessly stepping through), especially in async. But when I do I put in one or two a function and upto one an await. Then I make a breakpoint before that and debug if I didn’t find it by just a short look.
threaded - newest
Can you put something like
mold
orenv mold
for better portability?If not, I guess it’s not so bad to edit and do
git update-index --assume-unchanged .cargo/config.toml
but it’s a bit hacky since any further changes also get ignored.With all the respect to the author and his
wild
experiments, that title does not match the linker-only focus of the content.So not only the post ended up with two (IMHO) bad recommendations (disabling debug info, building non-relocatable binaries with musl). But it also didn’t mention other important factors like
codegen-units
andcodegen-backend
. Since you know, code generation is the other big contributor to the cycle time (the primary contributor even, in many cases). There is also other relevant options likelto
andopt-level
.Let’s assume that
opt-level
shouldn’t be changed from defaults for no good reason.With
codegen-units
, it’s not the default that is the problem, but the fact that some projects set it to 1 (for performance optimization reasons), but without adding a separate profile for development release builds (let’s call itrelease-dev
).Same goes for
lto
, where you can have it set to“full”
in your optimized profile, and completely“off”
inrelease-dev
.And finally, with
codegen-backend
, you can enjoy what is probably the biggest speed up in the cycle by usingcranelift
in yourrelease-dev
profile.And of course you are not limited to just two release profiles. I usually use 3-4 myself. Profile inheritance makes this easy.
And finally, you can set/not set some of those selectively for your dependencies. For example, not using
cranelift
for dependencies can render the runtime performance delta negligible in some projects.Using the parallel rustc front-end might become an interesting option too, but it’s not ready yet.
I think you’re being way too harsh.
The focus on linking was because this post is introducing his liker project.
OP ignore this naysayer.
🙂
Ok that was maybe a bit unfair!
Huh, I did not know that you can speed up builds by stripping debug info, need to try that out :)
For me the biggest speedup in my workflow was not through actually cutting down on the build time but rather using cargo watch. With
cargo watch -x run
, it automatically rebuilds and runs on any change so by the time I switch to the terminal it’s almost completely ready.I can imagine this to tank my PC performance, especially on large projects lol
I weep for the time lost on debugging with println. Good grief. It’s like having access to a time stopping ability and going “nah, I like trying to add a marker and tracing footsteps”.
Yes, for multi threaded workloads there aren’t many options, but most are single threaded and eschewing a debugger is bonkers to me.
Anti Commercial-AI license
Anyone who actually writes Rust code knows about tracing my friend.
We also have the ever useful
#[track_caller]
/Location::caller().And it’s needless to say that dbg!() also exists, which is better than manual printing for quick debugging.
So there exists a range of options setting between simple printing, and having to resort to using gdb/lldb (possibly with rr).
But yes, skipping debugging symbols was a bad suggestion.
This is always one of the first things I setup on a project and teach or encourage my teams to do… I’m always surprised how many devs would rather use print statements all the time (not just in Rust, but especially JS/TS) when it only takes like 5 minutes to configure the debugger. Maybe 10 minutes if you need to search how to open the debugging port in Chrome/FF.
I have to admit I still readily reach for dbg! to narrow down where the problem is happening (instead of endlessly stepping through), especially in async. But when I do I put in one or two a function and upto one an await. Then I make a breakpoint before that and debug if I didn’t find it by just a short look.