Repository navigation
Make Cache.get as fast on a hit as in 5.6.3 again - #35
Merged
Merged
Conversation
…en asked, restoring 5.6.3 hit speed.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cache.gethas been about 5% slower on a hit than in 5.6.3 since 5.7.0. The cause is thestore_timeflag added in PR #16. Everygetpaid for it, even whenstore_timewasn't asked for:store_time. Each extra column costs about 75 ns per hit (1655 ns for the 6-column query vs 1730 ns withstore_time), roughly 3%._meta_result()ran twice per call, once to wrap the default and once to wrap the result, at about 25–30 ns each, roughly 2.5%.FanoutCache.getandDjangoCache.getgo throughCache.get, so they had the same slowdown.Change (
Cache.getincore.py):store_timeis selected only whenstore_time=True. Otherwise the query is the 6-column one from 5.6.3._meta_result()runs only whenexpire_time,tagorstore_timeis asked for. A plaingetreturns the value directly.getgets a scopedtoo-many-branches,too-many-statementsdisable. Splitting it into helpers would add a function call to every hit, which is the kind of cost this removes.CHANGELOG.mdentry underUnreleased.Measured with interleaved runs: each build in its own venv on the Python 3.14.6 GIL build, SQLite 3.53.1, Apple M5 Pro, 20 rounds in random order. The ratio is per round against PyPI diskcache 5.6.3, and a second 5.6.3 venv gives the noise floor.
A bisect of every commit from 5.6.3 to master put the whole step at the
store_timecommit (−1.4% before it, +4.6% after). Nothing between 5.7.0 and master changedgetspeed.Not in this PR: Django set is still about 2% slower than 5.6.3. That comes from the fork gate from PR #13, which every write transaction passes through (about 430 ns).
Cache.setwithout an expire stays 12–14% faster than 5.6.3, thanks to the partial indexes.Checked:
store_time,expire_timeandtagtests cover both query shapes on the fast and transaction paths.bluecheck,flake8,isortcheckandpylintpass.