Skip to content

Conversation

@scho-furiosa
Copy link

@scho-furiosa scho-furiosa commented Feb 10, 2026

Hello, everyone.

My colleague @chaehhyun found that there are some regressions due to the clone in next during a profiling. We suspect ix.clone() inside Baseiter::next is the culprit, but not 100% for sure as of now. We are still experimenting its impact internally.

I have a couple of questions:

  • I am curious if the cloning of index in next is intentional.
  • If it is not the case, is there any pre-existing perf test in CI?

Thank you.

There is an avoidable `clone` in `next`.

This commit introduces `next_for_mut`, which is similar to `next_for`,
but updates the key in-place, and uses it in `next` instead.
@akern40
Copy link
Collaborator

akern40 commented Feb 11, 2026

Hello! Sorry to hear about a regression. Can you provide a minimal working example of the regression? Or some additional debug information?

@akern40
Copy link
Collaborator

akern40 commented Feb 11, 2026

Also, what version caused the regression?

@scho-furiosa
Copy link
Author

Also, what version caused the regression?

We are using the version 0.15.6. That said, I do not think this issue is related to the version, since the line ix.clone() has been there since its initial commit 2014.

Can you provide a minimal working example of the regression? Or some additional debug information?

AFAIU, this can be problematic when there are many dimensions (probably bigger than 6, i.e. IxDyn), so the cloning of the key is expensive. Basically, I just think the cloning of the key is unnecessary for normal iteration.

Re the minimal example, I am still curious if there are perf tests in the repo, or if you want it to have. This "cloning more or less" is not about functional correctness, so it is unclear which type of minimal example you have in your mind.

@akern40
Copy link
Collaborator

akern40 commented Feb 11, 2026

Ah thank you for the clarification. A "regression" is usually meant as a drop in performance or correctness when compared to a previous version, so I thought this was behavior you were seeing after an upgrade.

Unfortunately, performance is a known issue when using dynamic-dimensioned arrays. I haven't had a chance yet to look into the cause, but it's possible that this fix would help. I'd be happy to follow up and test to see if it improves speed. This is where a minimal example would help: the smallest possible code that exhibits the slow behavior that you're seeing.

There are some limited benchmarks in the library, but nothing comprehensive.

@akern40
Copy link
Collaborator

akern40 commented Feb 11, 2026

These changes look good, I appreciate the contribution! I'll put together a small benchmark to ensure that it has a positive impact on performance (I'm 99% sure that it will) and then I will merge the changes.

Comment on lines 199 to 201
fn next_for(&self, index: Self) -> Option<Self>
{
let mut index = index;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't this function calls next_for_mut now?

let mut index = index;
self.next_for_mut(&mut index)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants