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

Improve performance of expo by multiplying previous result #103

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

whonore
Copy link

@whonore whonore commented Sep 11, 2020

This computes the exponential by multiplying the previous result by base instead of computing it from scratch with ** each time, which seems to be about an order of magnitude faster. On my machine the following tests report around 2.63 seconds for expo_old and 0.10 for expo_new.

def expo_old(base=2, factor=1, max_value=None):
    n = 0
    while True:
        a = factor * base ** n
        if max_value is None or a < max_value:
            yield a
            n += 1
        else:
            yield max_value

def expo_new(base=2, factor=1, max_value=None):
    a = 1
    while True:
        if max_value is None or a < max_value:
            yield factor * a
            a *= base
        else:
            yield max_value

import timeit

for e in (expo_old(), expo_new()):
    print(timeit.timeit('for i in range(50): next(e)', globals={'e': e}, number=1000))

@bgreen-litl
Copy link
Member

This seems good to me.

Just curious, did you run into this because you in your use case the number of retries was very high?

@whonore
Copy link
Author

whonore commented Sep 15, 2020

No, I was just browsing the code and noticed that some work was unnecessarily re-done on each loop. I think it's pretty unlikely that anyone would reach enough retries for this to actually make much of a difference, but I figured I'd submit it anyway since it's such a simple change.

@gaby
Copy link

gaby commented Oct 11, 2021

Any chance this can get merged? PR has been open for over a year.

@whonore
Copy link
Author

whonore commented Feb 21, 2023

Ping?

while True:
a = factor * base ** n
if max_value is None or a < max_value:

Choose a reason for hiding this comment

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

This max_value condition doesn't work properly with your changes, it needs to be updated a bit, like this, but still 24x faster than the original:

    base_n = 1
    while True:
        a = factor * base_n
        if max_value is None or a < max_value:
            yield a
            base_n *= base

Copy link
Author

Choose a reason for hiding this comment

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

Good catch, thanks.

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.

4 participants