-
-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize parallel execution when it's only one task
See discussion in issue #190. Also, run coverage in Python 3.10, since running in Python 3.11 reports false negatives in test_lists (probably bug in coverage).
- Loading branch information
Showing
5 changed files
with
83 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -441,7 +441,7 @@ def execute_fields( | |
if is_awaitable(result): | ||
append_awaitable(response_name) | ||
|
||
# If there are no coroutines, we can just return the object | ||
# If there are no coroutines, we can just return the object. | ||
if not awaitable_fields: | ||
return results | ||
|
||
|
@@ -450,12 +450,17 @@ def execute_fields( | |
# will yield this same map, but with any coroutines awaited in parallel and | ||
# replaced with the values they yielded. | ||
async def get_results() -> Dict[str, Any]: | ||
results.update( | ||
zip( | ||
awaitable_fields, | ||
await gather(*(results[field] for field in awaitable_fields)), | ||
if len(awaitable_fields) == 1: | ||
# If there is only one field, avoid the overhead of parallelization. | ||
field = awaitable_fields[0] | ||
results[field] = await results[field] | ||
else: | ||
results.update( | ||
zip( | ||
awaitable_fields, | ||
await gather(*(results[field] for field in awaitable_fields)), | ||
) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Cito
Author
Member
|
||
) | ||
) | ||
return results | ||
|
||
return get_results() | ||
|
@@ -758,13 +763,18 @@ async def await_completed(item: Any, item_path: Path) -> Any: | |
|
||
# noinspection PyShadowingNames | ||
async def get_completed_results() -> List[Any]: | ||
for index, result in zip( | ||
awaitable_indices, | ||
await gather( | ||
*(completed_results[index] for index in awaitable_indices) | ||
), | ||
): | ||
completed_results[index] = result | ||
if len(awaitable_indices) == 1: | ||
# If there is only one index, avoid the overhead of parallelization. | ||
index = awaitable_indices[0] | ||
completed_results[index] = await completed_results[index] | ||
else: | ||
for index, result in zip( | ||
awaitable_indices, | ||
await gather( | ||
*(completed_results[index] for index in awaitable_indices) | ||
), | ||
): | ||
completed_results[index] = result | ||
return completed_results | ||
|
||
return get_completed_results() | ||
|
@@ -907,7 +917,7 @@ def complete_object_value( | |
|
||
# If there is an `is_type_of()` predicate function, call it with the current | ||
# result. If `is_type_of()` returns False, then raise an error rather than | ||
# continuing execution. | ||
# continuing execution. | ||
if return_type.is_type_of: | ||
is_type_of = return_type.is_type_of(result, info) | ||
|
||
|
@@ -943,7 +953,7 @@ def collect_subfields( | |
# We cannot use the field_nodes themselves as key for the cache, since they | ||
# are not hashable as a list. We also do not want to use the field_nodes | ||
# themselves (converted to a tuple) as keys, since hashing them is slow. | ||
# Therefore we use the ids of the field_nodes as keys. Note that we do not | ||
# Therefore, we use the ids of the field_nodes as keys. Note that we do not | ||
# use the id of the list, since we want to hit the cache for all lists of | ||
# the same nodes, not only for the same list of nodes. Also, the list id may | ||
# even be reused, in which case we would get wrong results from the cache. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Cito can I suggest moving this logic into a
async_gather
method on the ExecutionContext class so that it can overridden by a custom ExecutionContext class? That way the only change needed here would be to do this:Could also be a static method on the class.