Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exponential type/trait-checking behavior from linearly nested iterator adapters. #54175

Open
eddyb opened this issue Sep 13, 2018 · 3 comments
Open
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@eddyb
Copy link
Member

eddyb commented Sep 13, 2018

The following test takes an exponential amount of time to type-check the body of huge (at the time of this writing, reported by -Z time-passes under "item-types checking"):

#![crate_type = "lib"]

pub fn unit() -> std::iter::Empty<()> {
    std::iter::empty()
}

macro_rules! nest {
    ($inner:expr) => (unit().flat_map(|_| {
        $inner
    }).flat_map(|_| unit()))
}

macro_rules! nests {
    () => (unit());
    ($_first:tt $($rest:tt)*) => (nest!(nests!($($rest)*)))
}

pub fn huge() -> impl Iterator<Item = ()> {
    nests! {
        // 1/x * 6/5 seconds.
        4096 2048 1024 512 256 128 64 32 16 8 4 2

        // x * 6/5 seconds.
        1 2 4 8 // 16 32 64
    }
}

This has been reduced from an ambiguity-aware parse tree visitor, and you can see a partial reduction here: https://gist.github.com/eddyb/5f20b8f48b68c92f7d4f022a18c374f4#file-repro-rs.

cc @nikomatsakis

@estebank estebank added I-slow Issue: Problems and improvements with respect to performance of generated code. A-trait-system Area: Trait system A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. labels Sep 13, 2018
@eddyb eddyb removed the A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. label Sep 16, 2018
@eddyb
Copy link
Member Author

eddyb commented Sep 16, 2018

I should've tried to avoid impl Trait - AFAICT, it's irrelevant here, the compiler is just having a hard time dealing with the body of the function.

For the record, our workaround is using one big generator with many nested for loops, instead of nested iterator adaptors (see rust-lang/gll#47).

@eddyb
Copy link
Member Author

eddyb commented Sep 17, 2018

I just tested this and it seems to work really well, until it hits the recursion limit:

pub fn nest<F: FnMut() -> R, R>(mut f: F) -> R {
    f()
}

macro_rules! nest {
    ($inner:expr) => (nest(|| {
        $inner
    }))
}

macro_rules! nests {
    () => (());
    ($_first:tt $($rest:tt)*) => (nest!(nests!($($rest)*)))
}

So a for_each ("internal iteration") solution (with many nested closures) should work much better than one based on Iterator ("external iteration") adapters (with many of them nested in types).

@eddyb
Copy link
Member Author

eddyb commented Oct 20, 2018

@nikomatsakis Do you think this could be caused by the closures returning adapters, as opposed to them being chained without closures? I might try a different implementation as a workaround.

@nikic nikic added I-compiletime Issue: Problems and improvements with respect to compile times. and removed I-slow Issue: Problems and improvements with respect to performance of generated code. labels Dec 15, 2018
@jonas-schievink jonas-schievink added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 18, 2019
@jonas-schievink jonas-schievink added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Mar 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants