Skip to content

Conversation

bdraco
Copy link
Member

@bdraco bdraco commented Nov 29, 2024

We end up doing the same modification to URL objects quite frequently. Because URL objects are immutable, when this happens the self._cache is lost and has to be reconstructed for the new URL object that is produced. Additionally, we had ended up with a few places where the object.__new__(URL) was inlined because it was faster. We can move this all behind an lru_cache which ensures self._cache is preserved if the parts are in the cache which is the common case for most applications. With this change we can centralize most of the __new__ construction and make the code a bit more DRY.

Copy link

codspeed-hq bot commented Nov 29, 2024

CodSpeed Performance Report

Merging #1434 will improve performances by 85.74%

Comparing dry_from_parts (ca72808) with master (22544b1)

Summary

⚡ 20 improvements
✅ 65 untouched benchmarks

Benchmarks breakdown

Benchmark master dry_from_parts Change
test_update_query_empty 94.9 µs 65.3 µs +45.22%
test_update_query_none 90.2 µs 61.1 µs +47.56%
test_url_extend_query_existing_query_string 151.8 µs 126.5 µs +19.99%
test_url_join 251.9 µs 208.8 µs +20.6%
test_url_joinpath 657.3 µs 546.9 µs +20.18%
test_url_joinpath_encoded 619.2 µs 509.8 µs +21.45%
test_url_joinpath_encoded_long 962.6 µs 853.9 µs +12.73%
test_url_joinpath_with_truediv 750.6 µs 644.1 µs +16.54%
test_url_with_fragment 299 µs 189.5 µs +57.76%
test_url_with_host 492.1 µs 373.3 µs +31.81%
test_url_with_name 473.2 µs 372.2 µs +27.13%
test_url_with_password 447.1 µs 332.7 µs +34.38%
test_url_with_path 325.8 µs 214.2 µs +52.1%
test_url_with_path_parent 438.1 µs 333.1 µs +31.49%
test_url_with_path_relative 231.9 µs 124.9 µs +85.74%
test_url_with_port 436.5 µs 316.3 µs +37.99%
test_url_with_scheme 265.9 µs 169.1 µs +57.25%
test_url_with_user 438 µs 320.9 µs +36.5%
test_with_query_empty 112.2 µs 83.3 µs +34.75%
test_with_query_none 107.7 µs 79.2 µs +36.01%

Copy link

codecov bot commented Nov 29, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.10%. Comparing base (22544b1) to head (ca72808).
Report is 35 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1434      +/-   ##
==========================================
- Coverage   96.11%   96.10%   -0.02%     
==========================================
  Files          31       31              
  Lines        5871     5855      -16     
  Branches      348      348              
==========================================
- Hits         5643     5627      -16     
  Misses        202      202              
  Partials       26       26              
Flag Coverage Δ
CI-GHA 96.10% <100.00%> (-0.02%) ⬇️
MyPy 49.25% <97.14%> (-0.11%) ⬇️
OS-Linux 99.55% <100.00%> (-0.01%) ⬇️
OS-Windows 99.62% <100.00%> (-0.01%) ⬇️
OS-macOS 99.30% <100.00%> (-0.01%) ⬇️
Py-3.10.11 99.28% <100.00%> (-0.01%) ⬇️
Py-3.10.15 99.51% <100.00%> (-0.01%) ⬇️
Py-3.11.10 99.51% <100.00%> (-0.01%) ⬇️
Py-3.11.9 99.28% <100.00%> (-0.01%) ⬇️
Py-3.12.7 99.51% <100.00%> (-0.01%) ⬇️
Py-3.13.0 99.51% <100.00%> (-0.01%) ⬇️
Py-3.9.13 99.24% <100.00%> (-0.01%) ⬇️
Py-3.9.20 99.47% <100.00%> (-0.01%) ⬇️
Py-pypy7.3.16 99.53% <100.00%> (-0.01%) ⬇️
Py-pypy7.3.17 99.55% <100.00%> (-0.01%) ⬇️
VM-macos-latest 99.30% <100.00%> (-0.01%) ⬇️
VM-ubuntu-latest 99.55% <100.00%> (-0.01%) ⬇️
VM-windows-latest 99.62% <100.00%> (-0.01%) ⬇️
pytest 99.55% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bdraco
Copy link
Member Author

bdraco commented Nov 29, 2024

Looking at the distribution of calls. It makes sense to close #1433 and merge a combination of this and #1432

@bdraco
Copy link
Member Author

bdraco commented Nov 29, 2024

Hit rate looks great

2024-11-29 11:58:55.494 CRITICAL (SyncWorker_0) [homeassistant.components.profiler] Cache stats for lru_cache <function from_parts at 0x7ff1e12c5300> at /usr/local/lib/python3.13/site-packages/yarl/_url.py: CacheInfo(hits=2404, misses=502, maxsize=128, currsize=128)
...
2024-11-29 12:15:40.829 CRITICAL (SyncWorker_3) [homeassistant.components.profiler] Cache stats for lru_cache <function from_parts at 0x7ff1e12c5300> at /usr/local/lib/python3.13/site-packages/yarl/_url.py: CacheInfo(hits=5077, misses=959, maxsize=128, currsize=128)

Also we end up with a massive improvement in the self._cache hit rate because we don't have to rebuild it every time we modify the url if its already in the cache

@psf-chronographer psf-chronographer bot added the bot:chronographer:provided There is a change note present in this PR label Nov 29, 2024
@bdraco bdraco changed the title DNM: Experiment with making from_parts an LRU Make from_parts and LRU to increase the chance we can preserve the internal cache Nov 29, 2024
@bdraco bdraco changed the title Make from_parts and LRU to increase the chance we can preserve the internal cache Make from_parts a LRU to increase the chance we can preserve the internal cache Nov 29, 2024
@bdraco bdraco marked this pull request as ready for review November 29, 2024 18:17
@bdraco bdraco merged commit e3a282e into master Nov 29, 2024
46 of 48 checks passed
@bdraco bdraco deleted the dry_from_parts branch November 29, 2024 18:23
@bdraco
Copy link
Member Author

bdraco commented Nov 30, 2024

2024-11-29 19:42:14.766 CRITICAL (SyncWorker_5) [homeassistant.components.profiler] Cache stats for lru_cache <function from_parts_uncached at 0x7f1095e91440> at /usr/local/lib/python3.13/site-packages/yarl/_url.py: CacheInfo(hits=13122, misses=228, maxsize=128, currsize=128)

@bdraco
Copy link
Member Author

bdraco commented Nov 30, 2024

Thats after startup ~100 minutes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot:chronographer:provided There is a change note present in this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant