gh-102221: speed up math.lcm by swapping numbers#111450
gh-102221: speed up math.lcm by swapping numbers#111450kevin1kevin1k wants to merge 7 commits intopython:mainfrom
Conversation
|
Hi @corona10 I am contributing the PR during the PyCon APAC 2023 sprint; please review it if you have time (seems I am not able to assign reviewers). Thanks! |
350b32f to
2674494
Compare
| g = _PyLong_GCD(a, b); | ||
|
|
||
| /* Make sure a <= b to speed up (a // g) * b. */ | ||
| if (PyObject_RichCompareBool(b, a, Py_LT)) { |
There was a problem hiding this comment.
PyObject_RichCompareBool() can fail and set error.
What if arguments are negative?
Is there a practical difference between comparing values of integers and only their sizes?
There was a problem hiding this comment.
Oh thanks for the reminder, I would add some checks on the compared result.
On the other hand the comment #102221 (comment) in the issue seems to agree with your point: it suffices to compare the sizes (bits) of them. Let me modify so.
There was a problem hiding this comment.
The idea seems fine in principle, but I agree with others that we want to compare sizes rather than actual values - and as @serhiy-storchaka notes, the current code doesn't seem like the right solution if arguments could be negative.
So there are really two separate issues here:
- make sure that whatever swapping logic is implemented doesn't depend on signs of the inputs
- decide how fine-grained a comparison we want, and benchmark - do we want to compare absolute values? compare bit counts? compare limb counts? I'd expect that comparing limb counts would be enough.
|
What is a "limb count"? I would consider two options:
And then benchmark. |
Sorry, "digit count" would be better terminology for this context. ("limb" is GMP terminology, though I think it's more widespread than that; "digit" has the issue that it's somewhat ambiguous, since some might interpret it to mean with "decimal digit".) |
|
@kevin1kevin1k are you interested in addressing reviews? BTW, to compare sizes you could use private |
Sorry to all for the late response! I am willing to continue working on this, and thanks for the pointer to the helper function. |
7bdc2c5 to
2e0bcbb
Compare
|
@kevin1kevin1k, please avoid force-pushing PR's. |
2e0bcbb to
e1af338
Compare
e1af338 to
e35ba2a
Compare
|
@skirpichev @serhiy-storchaka I've rebased with new changes:
Using the similar profiling code that @pochmann provided in the issue:
|
skirpichev
left a comment
There was a problem hiding this comment.
I've rebased with new changes
You have asked to not do this. @kevin1kevin1k, please avoid altering commit history next time in any way.
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
|
Sorry I did not notice the previous comment on not force pushing, and thanks for the reminders. I will not do it in the future. |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Well, it works, and brings speed up. But I tried other algorithm, and it brings larger speed up. Details are in the issue.
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
This comment was marked as resolved.
This comment was marked as resolved.
Yes I saw the discussion and find it interesting (and educative!). Will defer proceeding here until a conclusion is reached there. |
|
@kevin1kevin1k, could you fix merge conflict? |
|
This PR is stale because it has been open for 30 days with no activity. |
Sorry for the delay. I have merged and resolved the conflict. Now the changes are moved to @serhiy-storchaka is this still relevant per the discussion in #102221? |
Try to speed up lcm by ensuring
a <= bbefore each(a // g) * boperation.Some discussions:
long_lcm(res, x)be changed tolong_lcm(x, res)? This could save some swapping operationsgfor the swapping; could have introduced another one (mayberjust like in_PyLong_GCD)