Skip to content

Poor inlining of closures for vec::from_fn<T>() #6623

Closed
@dotdash

Description

@dotdash

When there are multiple calls to vec::from_fn<T>() with the same type T but different closures, the compiler chooses to generate only one copy of vec::from_fn<T>() and pass the closure as an argument. This is really bad for simple closures like the ones in vec::from_elem<int>() or vec::to_owned<int>()

extern mod std;

#[bench]
fn to_owned(b: &mut std::test::BenchHarness) {
  let x = [0, ..1000];
  do b.iter {
    vec::to_owned(x);
  }
}

#[bench]
fn from_elem(b: &mut std::test::BenchHarness) {
  do b.iter {
    vec::from_elem(1000, 0);
  }
}

fn main() {
}

Running these gives:

running 2 tests
test from_elem ... bench: 2060 ns/iter (+/- 0)
test to_owned ... bench: 2306 ns/iter (+/- 3)

But if I remove one of the functions and only keep the other, I get:

running 1 test
test from_elem ... bench: 425 ns/iter (+/- 3)

and

running 1 test
test to_owned ... bench: 883 ns/iter (+/- 0)

This causes a 10% performance hit for rustc --no-trans. 0m14.664s vs. 13.592s with from_elem modified not to call from_fn but having a literal copy of the code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions