Skip to content

Conversation

@cxzhong
Copy link
Contributor

@cxzhong cxzhong commented Nov 16, 2025

Refactor degree sequence generation to use generators, reducing memory usage. Fix #41187

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

Refactor degree sequence generation to use generators, reducing memory usage.
@cxzhong cxzhong requested a review from maxale November 16, 2025 14:53
@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 16, 2025

Can you help me check if the result is true? Thank you @maxale

@cxzhong cxzhong marked this pull request as ready for review November 16, 2025 15:57
@maxale
Copy link
Contributor

maxale commented Nov 16, 2025

These changes look good to me, but with respect to refactoring, I'd also suggest to change list to tuple to enable easy hashability. Thanks!

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 17, 2025

sage: sum(1 for _ in DegreeSequences(18))
675759564

The result is right. But it takes 11 minutes. Is it normal? @maxale

Updated degree sequences representation to use tuples instead of lists for consistency and improved performance.
@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 17, 2025

These changes look good to me, but with respect to refactoring, I'd also suggest to change list to tuple to enable easy hashability. Thanks!

I have used tuple instaed of list

Copy link
Contributor

@mantepse mantepse left a comment

Choose a reason for hiding this comment

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

Looks great!

Comment on lines +417 to +419
for N > i >= 0:
for 0 <= j < seq[i]:
s.append(i)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is so much faster than the python equivalent, it's still surprising me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you very much

Copy link
Contributor

Choose a reason for hiding this comment

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

@mantepse I tested the version using range() and they have the exact same performance (as long as there are cdef of the loop variables), cython is good at optimization nowadays. In fact it appears to be preferred style to use range() just like in Python instead of cython's for loop style (see some of @fchapoton 's pull requests)

Copy link
Contributor

Choose a reason for hiding this comment

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

The inner loop yes, but the outer seems much slower to me??? Maybe I did it wrong?

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't the inner loop with s.append(i) be better replaced with s.extend(i for _ in range(seq[i])) ?

Copy link
Contributor

@maxale maxale Nov 17, 2025

Choose a reason for hiding this comment

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

Actually both loops can be done inside a single call to s.extend() - that is:

s.extend(i for i in range(N-1, -1, -1) for _ in range(seq[i]))

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but unfortunately this is slower. Also, a8ce96d is a slowdown, but it is less significant than I thought.

@mantepse
Copy link
Contributor

Maybe it would make sense to implement a cardinality method using https://arxiv.org/abs/2301.07022, section 5.1. Note that go code is attached to the arxiv submission. I guess that translating the go code to python is a bit too much work, but perhaps one can implement a simple version.

@user202729
Copy link
Contributor

wait. Is returning a tuple instead of a list considered a breaking change? (although tuple is "better" in a way that it's immutable and hashable, as pointed out above)

Looks like the original author is no longer around, so I'll ask a few other frequent contributors. @tscrim @dimpase @saraedum

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 17, 2025

As suggestions I would like to use range instead of this loop

@saraedum
Copy link
Member

wait. Is returning a tuple instead of a list considered a breaking change? (although tuple is "better" in a way that it's immutable and hashable, as pointed out above)

Looks like the original author is no longer around, so I'll ask a few other frequent contributors. @tscrim @dimpase @saraedum

I don't think we'd usually consider this a breaking change. I don't think we have a clear policy on this.

@user202729
Copy link
Contributor

okay.

cf. #41038 where Family is considered not compatible with tuple

@mantepse
Copy link
Contributor

Do we really want to include the last commit (which is a slowdown)?

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 18, 2025

Do we really want to include the last commit (which is a slowdown)?

If It does not be slower much than before, I think it is acceptable. @user202729

@mantepse
Copy link
Contributor

Do we really want to include the last commit (which is a slowdown)?

If It does not be slower much than before, I think it is acceptable. @user202729

Yes, but is there any good reason to do it? The other loops in the same file are consistently done with the same syntax, and I don't see any advantage of imitating python style in this particular case.

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 18, 2025

Maybe I revert this

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 18, 2025

Do we really want to include the last commit (which is a slowdown)?

If It does not be slower much than before, I think it is acceptable. @user202729

Yes, but is there any good reason to do it? The other loops in the same file are consistently done with the same syntax, and I don't see any advantage of imitating python style in this particular case.

I have done this. Maybe revert is much faster

vbraun pushed a commit to vbraun/sage that referenced this pull request Nov 19, 2025
sagemathgh-41188: Refactor degree sequence functions
    
Refactor degree sequence generation to use generators, reducing memory
usage. Fix sagemath#41187

<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->



### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [ ] The title is concise and informative.
- [ ] The description explains in detail what this PR is about.
- [ ] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#41188
Reported by: Chenxin Zhong
Reviewer(s): Chenxin Zhong, Martin Rubey, Max Alekseyev, user202729
vbraun pushed a commit to vbraun/sage that referenced this pull request Nov 20, 2025
sagemathgh-41188: Refactor degree sequence functions
    
Refactor degree sequence generation to use generators, reducing memory
usage. Fix sagemath#41187

<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->



### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [ ] The title is concise and informative.
- [ ] The description explains in detail what this PR is about.
- [ ] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#41188
Reported by: Chenxin Zhong
Reviewer(s): Chenxin Zhong, Martin Rubey, Max Alekseyev, user202729
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prohibitive memory requirement in DegreeSequences

5 participants