From 5b43687da6820884c75531e89d6347bf285a3b2c Mon Sep 17 00:00:00 2001 From: Semyon Pupkov Date: Sat, 11 May 2024 08:41:06 -0400 Subject: [PATCH] Optimize has_intersection func Optimize `has_intersection` function. It uses in few places, but even so it might be optimized. New version: 1. Does not allocate new set 2. A bit of performance speedup ``` from sqlalchemy import util import timeit import functools a = {1, 2, 3} b = [2, 3, 4] t1 = timeit.Timer(functools.partial(util.has_intersection, a, b)) t2 = timeit.Timer(functools.partial(util.has_intersection2, a, b)) print("old", t1.timeit()) print("new", t2.timeit()) old 0.37196154199773446 new 0.29704541599494405 old 0.37331208398973104 new 0.29647241700149607 ``` ### Description ### Checklist This pull request is: - [x] A documentation / typographical / small typing error fix - Good to go, no issue or tests are needed - [ ] A short code fix - please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted. - Please include: `Fixes: #` in the commit message - please include tests. one line code fixes without tests will not be accepted. - [ ] A new feature implementation - please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look. - Please include: `Fixes: #` in the commit message - please include tests. **Have a nice day!** Closes: #11378 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/11378 Pull-request-sha: 258bf1af7c73c83502eb49240a996f5846c6a0a9 Change-Id: Ic1ec1448641304eba4751f55f1e3c2b217f7f352 --- lib/sqlalchemy/util/_collections.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 3d092a0223..34b435e05f 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -16,6 +16,7 @@ import typing from typing import Any from typing import Callable from typing import cast +from typing import Container from typing import Dict from typing import FrozenSet from typing import Generic @@ -401,15 +402,14 @@ def to_list(x: Any, default: Optional[List[Any]] = None) -> List[Any]: return list(x) -def has_intersection(set_, iterable): +def has_intersection(set_: Container[Any], iterable: Iterable[Any]) -> bool: r"""return True if any items of set\_ are present in iterable. Goes through special effort to ensure __hash__ is not called on items in iterable that don't support it. """ - # TODO: optimize, write in C, etc. - return bool(set_.intersection([i for i in iterable if i.__hash__])) + return any(i in set_ for i in iterable if i.__hash__) def to_set(x): -- 2.47.2