|
56 | 56 | TYPE_CHECKING, |
57 | 57 | ) |
58 | 58 | import unicodedata |
| 59 | +import collections.abc |
| 60 | +from itertools import islice |
59 | 61 | from base64 import b64encode, b64decode |
60 | 62 | from bisect import bisect_left |
61 | 63 | import datetime |
@@ -434,7 +436,7 @@ def time_snowflake(dt: datetime.datetime, /, *, high: bool = False) -> int: |
434 | 436 |
|
435 | 437 |
|
436 | 438 | def _find(predicate: Callable[[T], Any], iterable: Iterable[T], /) -> Optional[T]: |
437 | | - return next((element for element in iterable if predicate(element)), None) |
| 439 | + return next(filter(predicate, iterable), None) |
438 | 440 |
|
439 | 441 |
|
440 | 442 | async def _afind(predicate: Callable[[T], Any], iterable: AsyncIterable[T], /) -> Optional[T]: |
@@ -1037,17 +1039,18 @@ def escape_mentions(text: str) -> str: |
1037 | 1039 |
|
1038 | 1040 |
|
1039 | 1041 | def _chunk(iterator: Iterable[T], max_size: int) -> Iterator[List[T]]: |
1040 | | - ret = [] |
1041 | | - n = 0 |
1042 | | - for item in iterator: |
1043 | | - ret.append(item) |
1044 | | - n += 1 |
1045 | | - if n == max_size: |
1046 | | - yield ret |
1047 | | - ret = [] |
1048 | | - n = 0 |
1049 | | - if ret: |
1050 | | - yield ret |
| 1042 | + # Specialise iterators that can be sliced as it is much faster |
| 1043 | + if isinstance(iterator, collections.abc.Sequence): |
| 1044 | + for i in range(0, len(iterator), max_size): |
| 1045 | + yield list(iterator[i : i + max_size]) |
| 1046 | + else: |
| 1047 | + # Fallback to slower path |
| 1048 | + iterator = iter(iterator) |
| 1049 | + while True: |
| 1050 | + batch = list(islice(iterator, max_size)) |
| 1051 | + if not batch: |
| 1052 | + break |
| 1053 | + yield batch |
1051 | 1054 |
|
1052 | 1055 |
|
1053 | 1056 | async def _achunk(iterator: AsyncIterable[T], max_size: int) -> AsyncIterator[List[T]]: |
|
0 commit comments