Skip to content

Slicing after str::starts_with performs unnecessary checks #72558

Open
@jhpratt

Description

@jhpratt

Without unsafe (playground)

pub struct Foo<'a> {
    string: &'a str,
}

impl Foo<'_> {
    pub fn bar(&mut self) -> Option<&str> {
        if self.string.starts_with("[[") {
            let bracket = &self.string[..1];
            self.string = &self.string[2..];
            Some(bracket)
        } else {
            None
        }
    }
}

With unsafe (playground)

pub struct Foo<'a> {
    string: &'a str,
}

impl Foo<'_> {
    pub fn bar(&mut self) -> Option<&str> {
        if self.string.starts_with("[[") {
            let bracket = unsafe { self.string.get_unchecked(..1) };
            self.string = unsafe { self.string.get_unchecked(2..) };
            Some(bracket)
        } else {
            None
        }
    }
}

I'm not terribly familiar with assembly, but the compiler is clearly performing checks where they aren't necessary. Given the knowledge that the string starts with a literal (in this case two ASCII bytes), we should be able to slice without any additional performance costs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-strArea: str and StringC-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions