Skip to content

cargo scripts cannot be run in release mode without workarounds #17423

Description

@ds84182

In the motivation section of the cargo script RFC there are 3 main motivations: collaboration, prototyping, and one-off utilities.

Collaboration? Sometimes reproduction cases require release mode to reproduce an issue.

Prototyping? If prototyping something other than a bog standard "hello world" (like working with images) you'll definitely run into performance issues.

One-off utilities? The dev profile is so slow that a single file bash or python script could accomplish some tasks significantly faster. Again, image processing, for example.

The only use case where compilation time would really matter to someone is when prototyping.

As a workaround it is possible to change the dev profile in the embedded manifest to match the default release profile, but being able to specify --release in the shebang line would be so much simpler.

I also think it would be beneficial to default to opt-level = 1 for dev builds, since it doesn't add much compilation overhead but improves runtime performance significantly.

Test script:

#!/usr/bin/env -S cargo -Zscript
---
[profile.release] # replace with dev to enable release
opt-level = 3
overflow-checks = false
debug = 0
debug-assertions = false
lto = true
incremental = false
codegen-units = 16

# uncomment for opt-level = 1 instead of 0
# [profile.dev]
# opt-level = 1

[dependencies]
image = { version = "0.25", default-features = false, features = ["png"] }
rand = "0.10"
---
fn main() {
    // A one-off utility to generate an opaque PNG with random pixels.
    const WH: usize = 4096;
    use rand::{Rng, SeedableRng};
    let start = std::time::Instant::now();
    let mut rng = rand::rngs::Xoshiro128PlusPlus::from_rng(&mut rand::rng());
    let pixels = (0..(WH * WH)).flat_map(|_| (rng.next_u32() | 0xFF000000).to_le_bytes()).collect::<Vec<u8>>();
    image::save_buffer("imagefoo.png", &pixels, WH as u32, WH as u32, image::ColorType::Rgba8).unwrap();
    println!("{:?}", start.elapsed());
}

With the default dev profile this takes 10 seconds. With opt-level 1 this takes 790ms, and with release mode this takes 170ms.

You could do the same in bash with imagemagick, which would be much faster than the default dev profile's performance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: enhancementS-triageStatus: This issue is waiting on initial triage.Z-scriptNightly: cargo script

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions