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

Make LIFO/HIFO accounting methods O(n*log(m)) #116

Merged
merged 15 commits into from
Jun 9, 2024
Merged

Conversation

qwhelan
Copy link
Contributor

@qwhelan qwhelan commented May 18, 2024

The LIFO and HIFO methods are unfortunately quadratic time (first test is trivial for LIFO):

One In, One Out
          FIFO      LIFO      HIFO
1     0.000268  0.000233  0.000233
10    0.001612  0.001335  0.001329
100   0.011682  0.012137  0.020656
1000  0.125671  0.126606  1.090273

Buys, then Sells
          FIFO      LIFO      HIFO
1     0.000235  0.000238  0.000233
10    0.001277  0.001378  0.001477
100   0.012547  0.021762  0.029432
1000  0.123024  1.113870  1.903485

The cases are the same as in #115 and assume the FIFO improvements there are merged.

The overall approach is to filter out exhausted lots early, so they do not need to be considered in each pass. In FIFO, this can be done by keeping track of another index. In LIFO and HIFO we introduce a heap where "active" lots are kept. The general for loop structure is kept to remove exhausted lots (as may occur when switching accounting methods across years), with the first non-exhausted lot guaranteed to be the one we are searching for. The use of heaps improves each loop to O(log m).

We translate the search criteria into a heap_key as Python only natively supports min heaps. It is likely that this key will need to be refined to guarantee deterministic behavior.

Due to test failures, this is not ready to merge but posting to start getting feedback.

And the results with this PR:

One In, One Out
          FIFO      LIFO      HIFO
1     0.000247  0.000250  0.000241
10    0.001286  0.001341  0.001632
100   0.011826  0.012560  0.012876
1000  0.123382  0.131119  0.133895

Buys, then Sells
          FIFO      LIFO      HIFO
1     0.000239  0.000262  0.000243
10    0.001301  0.001400  0.001477
100   0.012038  0.013003  0.015297
1000  0.125055  0.137297  0.171604

@qwhelan qwhelan changed the title Hifo Make LIFO/HIFO accounting methods O(n*log(m)) May 18, 2024
Copy link
Owner

@eprbell eprbell left a comment

Choose a reason for hiding this comment

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

This looks really interesting. I have only skimmed it for now, but I'm providing some early feedback.

src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
Copy link
Owner

@eprbell eprbell left a comment

Choose a reason for hiding this comment

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

I get the gist of what you're trying to do (use priority queues for hifo and lifo, instead of lists) and I think it holds a lot of promise. I went through the code and I'm providing some initial feedback: feel free to push back if any of my comments don't make sense to you (the code is still in progress and I may have misunderstood a few things).

src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
src/rp2/abstract_transaction.py Outdated Show resolved Hide resolved
src/rp2/in_transaction.py Outdated Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
src/rp2/plugin/accounting_method/fifo.py Outdated Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
@qwhelan
Copy link
Contributor Author

qwhelan commented Jun 2, 2024

Unit tests are now passing (other than a new false alarm on an external link)

@eprbell
Copy link
Owner

eprbell commented Jun 2, 2024

Unit tests are now passing (other than a new false alarm on an external link)

Oh, fantastic! Let me take another look.

@qwhelan
Copy link
Contributor Author

qwhelan commented Jun 3, 2024

@eprbell Refactor is complete and all tests are passing, but I'm guessing we'll need a round of cleanup or two. I didn't see your suggestion on row until just now but I'll implement that this week with any cleanup you suggest.

@eprbell
Copy link
Owner

eprbell commented Jun 3, 2024

@eprbell Refactor is complete and all tests are passing, but I'm guessing we'll need a round of cleanup or two. I didn't see your suggestion on row until just now but I'll implement that this week with any cleanup you suggest.

Great! I'll review.

@qwhelan qwhelan force-pushed the hifo branch 3 times, most recently from 6db4677 to 14db355 Compare June 7, 2024 07:56
Copy link
Owner

@eprbell eprbell left a comment

Choose a reason for hiding this comment

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

I have a few comments and questions here and there, but this looks really good: it'll be very beneficial to people with lots of transactions. We will also have to update the [plugin developer documentation] to mention the two plugin flavors (list vs heap).

src/rp2/in_transaction.py Outdated Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Outdated Show resolved Hide resolved
src/rp2/abstract_accounting_method.py Show resolved Hide resolved
src/rp2/plugin/accounting_method/lifo.py Show resolved Hide resolved
src/rp2/plugin/accounting_method/lifo.py Show resolved Hide resolved
src/rp2/plugin/accounting_method/hifo.py Outdated Show resolved Hide resolved
src/rp2/plugin/accounting_method/hifo.py Show resolved Hide resolved
src/rp2/abstract_transaction.py Outdated Show resolved Hide resolved
Copy link
Owner

@eprbell eprbell left a comment

Choose a reason for hiding this comment

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

LGTM! There are a couple of minor things still TBD (like updating the dev docs), but we shouldn't get blocked on that (I can work on that separately). Thanks again for this awesome set of optimizations!

@eprbell eprbell merged commit 93be086 into eprbell:main Jun 9, 2024
19 checks passed
@qwhelan qwhelan deleted the hifo branch June 10, 2024 00:44
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