Skip to content

Add LRU caching to tzoffset, tzstr and gettz#761

Merged
pganssle merged 4 commits intodateutil:masterfrom
gokcennurlu:lru_cache_tz
Oct 17, 2018
Merged

Add LRU caching to tzoffset, tzstr and gettz#761
pganssle merged 4 commits intodateutil:masterfrom
gokcennurlu:lru_cache_tz

Conversation

@gokcennurlu
Copy link
Copy Markdown
Contributor

@gokcennurlu gokcennurlu commented Jun 8, 2018

Summary of changes

I prepared a benchmark script and here are the results without the patch:

Benchmark:
https://gist.github.com/gokcennurlu/2b4e9d82e255c73e920c00ca5d26dcec

Results without patch:

3951.2012898921967 μs (tz.gettz() calls without storing values)
12.26398441940546 μs (tz.gettz() calls with storing values)


58.90091247856617 μs (tz.tzoffset() calls without storing values)
9.584207087755203 μs (tz.tzoffset() calls with storing values)


284.80793107300997 μs (tz.tzstr() calls without storing values)
7.534163072705269 μs (tz.tzstr() calls with storing values)

Results without patch:

27.99563854932785 μs (tz.gettz() calls without storing values)
28.635493479669094 μs (tz.gettz() calls with storing values)


22.882843017578125 μs (tz.tzoffset() calls without storing values)
25.380311533808708 μs (tz.tzoffset() calls with storing values)


24.550598114728928 μs (tz.tzstr() calls without storing values)
22.043749690055847 μs (tz.tzstr() calls with storing values)

'with storing values' means that a strong reference is kept in the scope (by doing a = func(..)) and lower values there explains the optimizing effect of currently used WeakValueDictionary based. caching.

Closes #691

Pull Request Checklist

  • Changes have tests
  • Authors have been added to AUTHORS.md
  • News fragment added in changelog.d. See CONTRIBUTING.md for details

@pganssle pganssle added this to the 2.8.0 milestone Jun 8, 2018
@gokcennurlu gokcennurlu changed the title Add LRU caching to tzoffset, tzstr and gettz WIP: Add LRU caching to tzoffset, tzstr and gettz Jun 8, 2018
@gokcennurlu
Copy link
Copy Markdown
Contributor Author

Fixed the 2.7 move_to_end compatibility error, interestingly all seems faster now. I guess if branchings there are more expensive, than get/sets, in our cases.

16.1310862749815 μs (tz.gettz() calls without storing values)
19.910280592739582 μs (tz.gettz() calls with storing values)


14.881940744817257 μs (tz.tzoffset() calls without storing values)
17.241469584405422 μs (tz.tzoffset() calls with storing values)


15.357932634651661 μs (tz.tzstr() calls without storing values)
14.645632356405258 μs (tz.tzstr() calls with storing values)

@gokcennurlu
Copy link
Copy Markdown
Contributor Author

I am aware that CI fails and will fix tzstr's tests by doing the same I've done for tzoffset's tests. I'll cleanup the commits and might add comments, but cache's logic is ready IMO.

We can add test for set_gettz_cache_size too, I believe.

@gokcennurlu gokcennurlu force-pushed the lru_cache_tz branch 2 times, most recently from be4fbbb to 6719b6c Compare June 14, 2018 13:34
@gokcennurlu gokcennurlu changed the title WIP: Add LRU caching to tzoffset, tzstr and gettz Add LRU caching to tzoffset, tzstr and gettz Jun 14, 2018
@gokcennurlu
Copy link
Copy Markdown
Contributor Author

Sorry for delaying this. I cleaned up the commits a little bit and I think it is ready for review.

@pganssle
Copy link
Copy Markdown
Member

No problem on delay. If you notice the project board review is currently the bottleneck.

pganssle added a commit to gokcennurlu/dateutil that referenced this pull request Sep 24, 2018
pganssle added a commit to gokcennurlu/dateutil that referenced this pull request Sep 24, 2018
Copy link
Copy Markdown
Member

@pganssle pganssle left a comment

Choose a reason for hiding this comment

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

@gokcennurlu I believe this is ready to merge. Can you review the changelog and AUTHORS.md changes that I added to make sure you are adequately credited before I merge?

pganssle added a commit to gokcennurlu/dateutil that referenced this pull request Oct 16, 2018
gokcennurlu and others added 4 commits October 16, 2018 14:21
Caching had been switched to use `weakrefs` in order to reuse instances if they
are still alive, by dateutil#635. This introduces a LRU cache to the mentioned functions
in order to prevent the instances created by them getting dealloc'd and alloc'd
unnecessarily, in situations like this:

```python
for i in range(100):
    tz.gettz('America/New_York')
```

`tz.tzoffset` and `tz.tzstr` get a LRU cache with size of 8.
`tz.gettz`'s cache starts with 8 by default and can be modified by the
introduced `tz.set_cache_size(int)`

Closes dateutil#691
@pganssle pganssle merged commit 83df62a into dateutil:master Oct 17, 2018
@gokcennurlu gokcennurlu deleted the lru_cache_tz branch October 22, 2018 23:35
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