Skip to content

removing needless .collect() in the middle of iterator chain reduces performance significantly #140873

Open
@cyrgani

Description

@cyrgani

reproduction (not minimal):
cyrgani/regulus@6c6dd75
command: cargo run --release -- tests/programs/sorting_tests.re

The relevant part is this:
https://github.com/cyrgani/regulus/blob/6c6dd758d3eadf0383b22d1acf2d7d9ccf21ac04/regulus/src/state.rs#L60-L82

With the currently present function (also below), the given test above takes about 400ms for me.

    pub fn get(&self, name: impl AsRef<str>) -> Option<&Atom> {
        let candidates = self
            .data
            .iter()
            .filter_map(|(ident, val)| {
                if ident.ident == name.as_ref() {
                    if true {
                        //let Source::Regular { .. } = ident.source {
                        Some((ident.source, val))
                    } else {
                        None
                    }
                } else {
                    None
                }
            })
            .collect::<Vec<_>>();

        candidates
            .into_iter()
            .max_by_key(|(source, _)| source.layer())
            .map(|(_, val)| val)
    }

It would seem logical now that removing the needless .collect() and .into_iter() should improve runtime (or at least not change it, if the compiler can optimize the allocation out). Instead, the simpler function causes the test to take around 600ms now (50% longer):

    pub fn get(&self, name: impl AsRef<str>) -> Option<&Atom> {
        self
            .data
            .iter()
            .filter_map(|(ident, val)| {
                if ident.ident == name.as_ref() {
                    if true {
                        //let Source::Regular { .. } = ident.source {
                        Some((ident.source, val))
                    } else {
                        None
                    }
                } else {
                    None
                }
            }
            .max_by_key(|(source, _)| source.layer())
            .map(|(_, val)| val)
    }

@rustbot label C-optimization I-slow E-needs-mcve

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.S-needs-reproStatus: This issue has no reproduction and needs a reproduction to make progress.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