Skip to content

perf: optimize scanl O(n²) --> O(n) #37

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

walking-octopus
Copy link
Contributor

@walking-octopus walking-octopus commented Apr 17, 2025

append and last are both O(n), so calling them in a loop resulted in O(n²) time-complexity.

The PR replaces them with a plain loop that accumulates results using cons and reverses them.

I hope the code fits the expected style.

Benchmark

(time (void (scanl-ref + (range #e1e5))))
;; cpu time: 74668 real time: 75829 gc time: 11320

(time (void (scanl + (range #e1e5))))
;; cpu time: 2 real time: 2 gc time: 0

With a 100,000-element list, the new implementation is ~38,000x faster.

Tests

stas@thinkpad-t14 ~/P/racket-algorithms (scanl)> raco test main.rkt
raco test: (submod (file "main.rkt") test)
72 tests passed

@walking-octopus
Copy link
Contributor Author

walking-octopus commented Apr 17, 2025

Inspired by Haskell, I also added a (scanl op seed xs) variant. I hope it's okay to do it in one PR. If you don't think that was a good idea, I can rebase and drop that commit. Thanks.

@walking-octopus walking-octopus changed the title perf: optimize scanl [O(n²) --> O(n)] perf: optimize scanl O(n²) --> O(n) Apr 17, 2025
@codereport codereport self-requested a review April 17, 2025 22:01
Copy link
Owner

@codereport codereport left a comment

Choose a reason for hiding this comment

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

can you merge master into this PR so the ci.yml changes are here?

@codereport
Copy link
Owner

can you merge master into this PR so the ci.yml changes are here?

Yea, i just pushed a fix. It is working now #38

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.

2 participants