From dfc3f899e5b81997a343b227100781f4c39a3464 Mon Sep 17 00:00:00 2001 From: Rongrong Date: Sun, 12 Nov 2023 20:55:13 +0800 Subject: [PATCH] Skip filtering ``CookieJar`` when the jar is empty or all cookies have expired (#7819) The filtering itself and its preparation in `CookieJar.filter_cookies()` is expensive. Sometimes there are no cookies in the jar or all cookies have expired. Skip filtering and its preparation in this case. Because the empty check is much cheaper than `_do_expiration()`, I think it deserves to be duplicated before and after calling `_do_expiration()`. ```console $ python3.11 -m timeit -s 'from collections import defaultdict; d=defaultdict(foo="bar")' \ > 'if not d: pass' 50000000 loops, best of 5: 8.3 nsec per loop $ python3.11 -m timeit -s 'from collections import defaultdict; d=defaultdict()' \ > 'if not d: pass' 50000000 loops, best of 5: 8.74 nsec per loop $ python3.11 -m timeit -s 'from aiohttp import CookieJar; cj = CookieJar()' \ > 'cj._do_expiration()' 200000 loops, best of 5: 1.86 usec per loop ``` --- CHANGES/7819.feature | 1 + CONTRIBUTORS.txt | 1 + aiohttp/cookiejar.py | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 CHANGES/7819.feature diff --git a/CHANGES/7819.feature b/CHANGES/7819.feature new file mode 100644 index 00000000000..6ff263abeb8 --- /dev/null +++ b/CHANGES/7819.feature @@ -0,0 +1 @@ +Skip filtering ``CookieJar`` when the jar is empty or all cookies have expired. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b9052c404dd..539a8807689 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -282,6 +282,7 @@ Robert Lu Robert Nikolich Roman Markeloff Roman Podoliaka +Rong Zhang Samir Akarioh Samuel Colvin Sean Hunt diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py index a35c15f344b..11ef9e288a7 100644 --- a/aiohttp/cookiejar.py +++ b/aiohttp/cookiejar.py @@ -234,7 +234,6 @@ def filter_cookies( self, request_url: URL = URL() ) -> Union["BaseCookie[str]", "SimpleCookie[str]"]: """Returns this jar's cookies filtered by their attributes.""" - self._do_expiration() if not isinstance(request_url, URL): warnings.warn( "The method accepts yarl.URL instances only, got {}".format( @@ -246,6 +245,13 @@ def filter_cookies( filtered: Union["SimpleCookie[str]", "BaseCookie[str]"] = ( SimpleCookie() if self._quote_cookie else BaseCookie() ) + if not self._cookies: + # Skip do_expiration() if there are no cookies. + return filtered + self._do_expiration() + if not self._cookies: + # Skip rest of function if no non-expired cookies. + return filtered hostname = request_url.raw_host or "" request_origin = URL() with contextlib.suppress(ValueError):