zexus 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/README.md +2513 -0
- package/bin/zexus +2 -0
- package/bin/zpics +2 -0
- package/bin/zpm +2 -0
- package/bin/zx +2 -0
- package/bin/zx-deploy +2 -0
- package/bin/zx-dev +2 -0
- package/bin/zx-run +2 -0
- package/package.json +66 -0
- package/scripts/README.md +24 -0
- package/scripts/postinstall.js +44 -0
- package/shared_config.json +24 -0
- package/src/README.md +1525 -0
- package/src/tests/run_zexus_tests.py +117 -0
- package/src/tests/test_all_phases.zx +346 -0
- package/src/tests/test_blockchain_features.zx +306 -0
- package/src/tests/test_complexity_features.zx +321 -0
- package/src/tests/test_core_integration.py +185 -0
- package/src/tests/test_phase10_ecosystem.zx +177 -0
- package/src/tests/test_phase1_modifiers.zx +87 -0
- package/src/tests/test_phase2_plugins.zx +80 -0
- package/src/tests/test_phase3_security.zx +97 -0
- package/src/tests/test_phase4_vfs.zx +116 -0
- package/src/tests/test_phase5_types.zx +117 -0
- package/src/tests/test_phase6_metaprogramming.zx +125 -0
- package/src/tests/test_phase7_optimization.zx +132 -0
- package/src/tests/test_phase9_advanced_types.zx +157 -0
- package/src/tests/test_security_features.py +419 -0
- package/src/tests/test_security_features.zx +276 -0
- package/src/tests/test_simple_zx.zx +1 -0
- package/src/tests/test_verification_simple.zx +69 -0
- package/src/zexus/__init__.py +28 -0
- package/src/zexus/__main__.py +5 -0
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
- package/src/zexus/advanced_types.py +401 -0
- package/src/zexus/blockchain/__init__.py +40 -0
- package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/crypto.py +463 -0
- package/src/zexus/blockchain/ledger.py +255 -0
- package/src/zexus/blockchain/transaction.py +267 -0
- package/src/zexus/builtin_modules.py +284 -0
- package/src/zexus/builtin_plugins.py +317 -0
- package/src/zexus/capability_system.py +372 -0
- package/src/zexus/cli/__init__.py +2 -0
- package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +707 -0
- package/src/zexus/cli/zpm.py +203 -0
- package/src/zexus/compare_interpreter_compiler.py +146 -0
- package/src/zexus/compiler/__init__.py +169 -0
- package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/bytecode.py +266 -0
- package/src/zexus/compiler/compat_runtime.py +277 -0
- package/src/zexus/compiler/lexer.py +257 -0
- package/src/zexus/compiler/parser.py +779 -0
- package/src/zexus/compiler/semantic.py +118 -0
- package/src/zexus/compiler/zexus_ast.py +454 -0
- package/src/zexus/complexity_system.py +575 -0
- package/src/zexus/concurrency_system.py +493 -0
- package/src/zexus/config.py +201 -0
- package/src/zexus/crypto_bridge.py +19 -0
- package/src/zexus/dependency_injection.py +423 -0
- package/src/zexus/ecosystem.py +434 -0
- package/src/zexus/environment.py +101 -0
- package/src/zexus/environment_manager.py +119 -0
- package/src/zexus/error_reporter.py +314 -0
- package/src/zexus/evaluator/__init__.py +12 -0
- package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +700 -0
- package/src/zexus/evaluator/core.py +891 -0
- package/src/zexus/evaluator/expressions.py +827 -0
- package/src/zexus/evaluator/functions.py +3989 -0
- package/src/zexus/evaluator/integration.py +396 -0
- package/src/zexus/evaluator/statements.py +4303 -0
- package/src/zexus/evaluator/utils.py +126 -0
- package/src/zexus/evaluator_original.py +2041 -0
- package/src/zexus/external_bridge.py +16 -0
- package/src/zexus/find_affected_imports.sh +155 -0
- package/src/zexus/hybrid_orchestrator.py +152 -0
- package/src/zexus/input_validation.py +259 -0
- package/src/zexus/lexer.py +571 -0
- package/src/zexus/logging.py +89 -0
- package/src/zexus/lsp/__init__.py +9 -0
- package/src/zexus/lsp/completion_provider.py +207 -0
- package/src/zexus/lsp/definition_provider.py +22 -0
- package/src/zexus/lsp/hover_provider.py +71 -0
- package/src/zexus/lsp/server.py +269 -0
- package/src/zexus/lsp/symbol_provider.py +31 -0
- package/src/zexus/metaprogramming.py +321 -0
- package/src/zexus/module_cache.py +89 -0
- package/src/zexus/module_manager.py +107 -0
- package/src/zexus/object.py +973 -0
- package/src/zexus/optimization.py +424 -0
- package/src/zexus/parser/__init__.py +31 -0
- package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
- package/src/zexus/parser/integration.py +86 -0
- package/src/zexus/parser/parser.py +3977 -0
- package/src/zexus/parser/strategy_context.py +7254 -0
- package/src/zexus/parser/strategy_structural.py +1033 -0
- package/src/zexus/persistence.py +391 -0
- package/src/zexus/plugin_system.py +290 -0
- package/src/zexus/policy_engine.py +365 -0
- package/src/zexus/profiler/__init__.py +5 -0
- package/src/zexus/profiler/profiler.py +233 -0
- package/src/zexus/purity_system.py +398 -0
- package/src/zexus/runtime/__init__.py +20 -0
- package/src/zexus/runtime/async_runtime.py +324 -0
- package/src/zexus/search_old_imports.sh +65 -0
- package/src/zexus/security.py +1407 -0
- package/src/zexus/stack_trace.py +233 -0
- package/src/zexus/stdlib/__init__.py +27 -0
- package/src/zexus/stdlib/blockchain.py +341 -0
- package/src/zexus/stdlib/compression.py +167 -0
- package/src/zexus/stdlib/crypto.py +124 -0
- package/src/zexus/stdlib/datetime.py +163 -0
- package/src/zexus/stdlib/db_mongo.py +199 -0
- package/src/zexus/stdlib/db_mysql.py +162 -0
- package/src/zexus/stdlib/db_postgres.py +163 -0
- package/src/zexus/stdlib/db_sqlite.py +133 -0
- package/src/zexus/stdlib/encoding.py +230 -0
- package/src/zexus/stdlib/fs.py +195 -0
- package/src/zexus/stdlib/http.py +219 -0
- package/src/zexus/stdlib/http_server.py +248 -0
- package/src/zexus/stdlib/json_module.py +61 -0
- package/src/zexus/stdlib/math.py +360 -0
- package/src/zexus/stdlib/os_module.py +265 -0
- package/src/zexus/stdlib/regex.py +148 -0
- package/src/zexus/stdlib/sockets.py +253 -0
- package/src/zexus/stdlib/test_framework.zx +208 -0
- package/src/zexus/stdlib/test_runner.zx +119 -0
- package/src/zexus/stdlib_integration.py +341 -0
- package/src/zexus/strategy_recovery.py +256 -0
- package/src/zexus/syntax_validator.py +356 -0
- package/src/zexus/testing/zpics.py +407 -0
- package/src/zexus/testing/zpics_runtime.py +369 -0
- package/src/zexus/type_system.py +374 -0
- package/src/zexus/validation_system.py +569 -0
- package/src/zexus/virtual_filesystem.py +355 -0
- package/src/zexus/vm/__init__.py +8 -0
- package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +420 -0
- package/src/zexus/vm/bytecode.py +428 -0
- package/src/zexus/vm/bytecode_converter.py +297 -0
- package/src/zexus/vm/cache.py +532 -0
- package/src/zexus/vm/jit.py +720 -0
- package/src/zexus/vm/memory_manager.py +520 -0
- package/src/zexus/vm/memory_pool.py +511 -0
- package/src/zexus/vm/optimizer.py +478 -0
- package/src/zexus/vm/parallel_vm.py +899 -0
- package/src/zexus/vm/peephole_optimizer.py +452 -0
- package/src/zexus/vm/profiler.py +527 -0
- package/src/zexus/vm/register_allocator.py +462 -0
- package/src/zexus/vm/register_vm.py +520 -0
- package/src/zexus/vm/ssa_converter.py +757 -0
- package/src/zexus/vm/vm.py +1392 -0
- package/src/zexus/zexus_ast.py +1782 -0
- package/src/zexus/zexus_token.py +253 -0
- package/src/zexus/zpm/__init__.py +15 -0
- package/src/zexus/zpm/installer.py +116 -0
- package/src/zexus/zpm/package_manager.py +208 -0
- package/src/zexus/zpm/publisher.py +98 -0
- package/src/zexus/zpm/registry.py +110 -0
- package/src/zexus.egg-info/PKG-INFO +2235 -0
- package/src/zexus.egg-info/SOURCES.txt +876 -0
- package/src/zexus.egg-info/dependency_links.txt +1 -0
- package/src/zexus.egg-info/entry_points.txt +3 -0
- package/src/zexus.egg-info/not-zip-safe +1 -0
- package/src/zexus.egg-info/requires.txt +14 -0
- package/src/zexus.egg-info/top_level.txt +2 -0
- package/zexus.json +14 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Async/Await Performance Optimizer for Zexus VM
|
|
3
|
+
|
|
4
|
+
Implements optimizations for async/await operations:
|
|
5
|
+
- Coroutine pooling to reduce allocation overhead
|
|
6
|
+
- Fast path for already-resolved futures
|
|
7
|
+
- Batch operation detection and optimization
|
|
8
|
+
- Inline async operations
|
|
9
|
+
|
|
10
|
+
Phase 8.4 of VM Optimization Project
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
import sys
|
|
15
|
+
from dataclasses import dataclass, field
|
|
16
|
+
from typing import Any, Callable, Coroutine, Optional, List, Dict
|
|
17
|
+
from collections import deque
|
|
18
|
+
from enum import Enum
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AsyncOptimizationLevel(Enum):
|
|
22
|
+
"""Async optimization levels"""
|
|
23
|
+
NONE = 0 # No optimization
|
|
24
|
+
BASIC = 1 # Coroutine pooling only
|
|
25
|
+
MODERATE = 2 # Pooling + fast paths
|
|
26
|
+
AGGRESSIVE = 3 # All optimizations including batch detection
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class AsyncStats:
|
|
31
|
+
"""Statistics for async operations"""
|
|
32
|
+
total_spawns: int = 0
|
|
33
|
+
total_awaits: int = 0
|
|
34
|
+
pooled_coroutines: int = 0
|
|
35
|
+
fast_path_hits: int = 0
|
|
36
|
+
batched_operations: int = 0
|
|
37
|
+
coroutine_reuses: int = 0
|
|
38
|
+
event_loop_skips: int = 0
|
|
39
|
+
|
|
40
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
41
|
+
"""Convert stats to dictionary"""
|
|
42
|
+
return {
|
|
43
|
+
'total_spawns': self.total_spawns,
|
|
44
|
+
'total_awaits': self.total_awaits,
|
|
45
|
+
'pooled_coroutines': self.pooled_coroutines,
|
|
46
|
+
'fast_path_hits': self.fast_path_hits,
|
|
47
|
+
'batched_operations': self.batched_operations,
|
|
48
|
+
'coroutine_reuses': self.coroutine_reuses,
|
|
49
|
+
'event_loop_skips': self.event_loop_skips,
|
|
50
|
+
'pool_hit_rate': self._pool_hit_rate(),
|
|
51
|
+
'fast_path_rate': self._fast_path_rate(),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
def _pool_hit_rate(self) -> float:
|
|
55
|
+
"""Calculate coroutine pool hit rate"""
|
|
56
|
+
if self.pooled_coroutines == 0:
|
|
57
|
+
return 0.0
|
|
58
|
+
return (self.coroutine_reuses / self.pooled_coroutines) * 100.0
|
|
59
|
+
|
|
60
|
+
def _fast_path_rate(self) -> float:
|
|
61
|
+
"""Calculate fast path hit rate"""
|
|
62
|
+
if self.total_awaits == 0:
|
|
63
|
+
return 0.0
|
|
64
|
+
return (self.fast_path_hits / self.total_awaits) * 100.0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class FastFuture:
|
|
68
|
+
"""
|
|
69
|
+
Lightweight future implementation for already-resolved values
|
|
70
|
+
|
|
71
|
+
Skips event loop overhead when value is immediately available.
|
|
72
|
+
About 5x faster than asyncio.Future for synchronous-like async code.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
__slots__ = ('_value', '_exception', '_done')
|
|
76
|
+
|
|
77
|
+
def __init__(self, value: Any = None, exception: Optional[Exception] = None):
|
|
78
|
+
self._value = value
|
|
79
|
+
self._exception = exception
|
|
80
|
+
self._done = True
|
|
81
|
+
|
|
82
|
+
def done(self) -> bool:
|
|
83
|
+
"""Check if future is done"""
|
|
84
|
+
return self._done
|
|
85
|
+
|
|
86
|
+
def result(self) -> Any:
|
|
87
|
+
"""Get result"""
|
|
88
|
+
if self._exception:
|
|
89
|
+
raise self._exception
|
|
90
|
+
return self._value
|
|
91
|
+
|
|
92
|
+
def exception(self) -> Optional[Exception]:
|
|
93
|
+
"""Get exception"""
|
|
94
|
+
return self._exception
|
|
95
|
+
|
|
96
|
+
def __await__(self):
|
|
97
|
+
"""Make it awaitable - fast path, no event loop"""
|
|
98
|
+
if self._exception:
|
|
99
|
+
raise self._exception
|
|
100
|
+
yield from [].__iter__() # Make it a generator
|
|
101
|
+
return self._value
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class CoroutinePool:
|
|
105
|
+
"""
|
|
106
|
+
Pool for reusing coroutine wrapper objects
|
|
107
|
+
|
|
108
|
+
Reduces allocation overhead by reusing coroutine frames.
|
|
109
|
+
Provides ~3x faster coroutine creation for small, frequently-called async functions.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(self, max_size: int = 100):
|
|
113
|
+
self.max_size = max_size
|
|
114
|
+
self.pool: deque = deque(maxlen=max_size)
|
|
115
|
+
self.stats = AsyncStats()
|
|
116
|
+
|
|
117
|
+
def get_wrapper(self, coro: Coroutine) -> Coroutine:
|
|
118
|
+
"""
|
|
119
|
+
Get a coroutine wrapper, reusing if available
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
coro: Coroutine to wrap
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Wrapped coroutine
|
|
126
|
+
"""
|
|
127
|
+
self.stats.pooled_coroutines += 1
|
|
128
|
+
|
|
129
|
+
if self.pool:
|
|
130
|
+
wrapper = self.pool.popleft()
|
|
131
|
+
self.stats.coroutine_reuses += 1
|
|
132
|
+
# Reset wrapper with new coroutine
|
|
133
|
+
wrapper._coro = coro
|
|
134
|
+
return wrapper
|
|
135
|
+
|
|
136
|
+
# Create new wrapper
|
|
137
|
+
return PooledCoroutineWrapper(coro, self)
|
|
138
|
+
|
|
139
|
+
def release_wrapper(self, wrapper):
|
|
140
|
+
"""
|
|
141
|
+
Release wrapper back to pool
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
wrapper: Wrapper to release
|
|
145
|
+
"""
|
|
146
|
+
if len(self.pool) < self.max_size:
|
|
147
|
+
self.pool.append(wrapper)
|
|
148
|
+
|
|
149
|
+
def clear(self):
|
|
150
|
+
"""Clear the pool"""
|
|
151
|
+
self.pool.clear()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class PooledCoroutineWrapper:
|
|
155
|
+
"""Wrapper for pooled coroutines"""
|
|
156
|
+
|
|
157
|
+
__slots__ = ('_coro', '_pool')
|
|
158
|
+
|
|
159
|
+
def __init__(self, coro: Coroutine, pool: CoroutinePool):
|
|
160
|
+
self._coro = coro
|
|
161
|
+
self._pool = pool
|
|
162
|
+
|
|
163
|
+
def __await__(self):
|
|
164
|
+
"""Forward to wrapped coroutine"""
|
|
165
|
+
return self._coro.__await__()
|
|
166
|
+
|
|
167
|
+
def send(self, value):
|
|
168
|
+
"""Forward send"""
|
|
169
|
+
return self._coro.send(value)
|
|
170
|
+
|
|
171
|
+
def throw(self, typ, val=None, tb=None):
|
|
172
|
+
"""Forward throw"""
|
|
173
|
+
return self._coro.throw(typ, val, tb)
|
|
174
|
+
|
|
175
|
+
def close(self):
|
|
176
|
+
"""Close and return to pool"""
|
|
177
|
+
try:
|
|
178
|
+
self._coro.close()
|
|
179
|
+
finally:
|
|
180
|
+
self._pool.release_wrapper(self)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class BatchAwaitDetector:
|
|
184
|
+
"""
|
|
185
|
+
Detects multiple independent await operations that can be batched
|
|
186
|
+
|
|
187
|
+
Analyzes async execution patterns and automatically converts
|
|
188
|
+
sequential awaits into parallel execution using asyncio.gather().
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
def __init__(self):
|
|
192
|
+
self.pending_awaits: List[Coroutine] = []
|
|
193
|
+
self.min_batch_size = 2
|
|
194
|
+
|
|
195
|
+
def add_await(self, coro: Coroutine) -> Optional[List[Coroutine]]:
|
|
196
|
+
"""
|
|
197
|
+
Add an await operation
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
coro: Coroutine to await
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Batch of coroutines if ready to execute, None otherwise
|
|
204
|
+
"""
|
|
205
|
+
self.pending_awaits.append(coro)
|
|
206
|
+
|
|
207
|
+
# Check if we should flush the batch
|
|
208
|
+
if len(self.pending_awaits) >= self.min_batch_size:
|
|
209
|
+
batch = self.pending_awaits
|
|
210
|
+
self.pending_awaits = []
|
|
211
|
+
return batch
|
|
212
|
+
|
|
213
|
+
return None
|
|
214
|
+
|
|
215
|
+
def flush(self) -> List[Coroutine]:
|
|
216
|
+
"""
|
|
217
|
+
Flush pending awaits
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
All pending coroutines
|
|
221
|
+
"""
|
|
222
|
+
batch = self.pending_awaits
|
|
223
|
+
self.pending_awaits = []
|
|
224
|
+
return batch
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class AsyncOptimizer:
|
|
228
|
+
"""
|
|
229
|
+
Main async/await optimizer
|
|
230
|
+
|
|
231
|
+
Provides multiple optimization strategies:
|
|
232
|
+
- Coroutine pooling
|
|
233
|
+
- Fast path for resolved futures
|
|
234
|
+
- Batch operation detection
|
|
235
|
+
- Event loop skip for immediate values
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
def __init__(
|
|
239
|
+
self,
|
|
240
|
+
level: AsyncOptimizationLevel = AsyncOptimizationLevel.MODERATE,
|
|
241
|
+
pool_size: int = 100
|
|
242
|
+
):
|
|
243
|
+
self.level = level
|
|
244
|
+
self.stats = AsyncStats()
|
|
245
|
+
|
|
246
|
+
# Coroutine pool (BASIC+)
|
|
247
|
+
self.coroutine_pool = None
|
|
248
|
+
if level.value >= AsyncOptimizationLevel.BASIC.value:
|
|
249
|
+
self.coroutine_pool = CoroutinePool(max_size=pool_size)
|
|
250
|
+
|
|
251
|
+
# Batch detector (AGGRESSIVE)
|
|
252
|
+
self.batch_detector = None
|
|
253
|
+
if level.value >= AsyncOptimizationLevel.AGGRESSIVE.value:
|
|
254
|
+
self.batch_detector = BatchAwaitDetector()
|
|
255
|
+
|
|
256
|
+
def spawn(self, coro: Coroutine) -> Coroutine:
|
|
257
|
+
"""
|
|
258
|
+
Optimize coroutine spawning
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
coro: Coroutine to spawn
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Optimized coroutine
|
|
265
|
+
"""
|
|
266
|
+
self.stats.total_spawns += 1
|
|
267
|
+
|
|
268
|
+
# Use pooling if enabled
|
|
269
|
+
if self.coroutine_pool and self.level.value >= AsyncOptimizationLevel.BASIC.value:
|
|
270
|
+
return self.coroutine_pool.get_wrapper(coro)
|
|
271
|
+
|
|
272
|
+
return coro
|
|
273
|
+
|
|
274
|
+
async def await_optimized(self, awaitable: Any) -> Any:
|
|
275
|
+
"""
|
|
276
|
+
Optimize await operation
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
awaitable: Object to await
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
Result of await
|
|
283
|
+
"""
|
|
284
|
+
self.stats.total_awaits += 1
|
|
285
|
+
|
|
286
|
+
# Fast path for already-resolved futures (MODERATE+)
|
|
287
|
+
if self.level.value >= AsyncOptimizationLevel.MODERATE.value:
|
|
288
|
+
if isinstance(awaitable, FastFuture):
|
|
289
|
+
self.stats.fast_path_hits += 1
|
|
290
|
+
self.stats.event_loop_skips += 1
|
|
291
|
+
return awaitable.result()
|
|
292
|
+
|
|
293
|
+
# Check if it's an already-done asyncio.Future
|
|
294
|
+
if isinstance(awaitable, asyncio.Future) and awaitable.done():
|
|
295
|
+
self.stats.fast_path_hits += 1
|
|
296
|
+
self.stats.event_loop_skips += 1
|
|
297
|
+
return awaitable.result()
|
|
298
|
+
|
|
299
|
+
# Regular await
|
|
300
|
+
return await awaitable
|
|
301
|
+
|
|
302
|
+
def create_resolved_future(self, value: Any) -> FastFuture:
|
|
303
|
+
"""
|
|
304
|
+
Create a fast future with resolved value
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
value: Value to wrap
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
FastFuture containing value
|
|
311
|
+
"""
|
|
312
|
+
return FastFuture(value=value)
|
|
313
|
+
|
|
314
|
+
def create_rejected_future(self, exception: Exception) -> FastFuture:
|
|
315
|
+
"""
|
|
316
|
+
Create a fast future with exception
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
exception: Exception to wrap
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
FastFuture containing exception
|
|
323
|
+
"""
|
|
324
|
+
return FastFuture(exception=exception)
|
|
325
|
+
|
|
326
|
+
async def gather_batch(self, coroutines: List[Coroutine]) -> List[Any]:
|
|
327
|
+
"""
|
|
328
|
+
Execute multiple coroutines in parallel
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
coroutines: Coroutines to execute
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
List of results
|
|
335
|
+
"""
|
|
336
|
+
if not coroutines:
|
|
337
|
+
return []
|
|
338
|
+
|
|
339
|
+
if len(coroutines) == 1:
|
|
340
|
+
return [await coroutines[0]]
|
|
341
|
+
|
|
342
|
+
self.stats.batched_operations += len(coroutines)
|
|
343
|
+
return await asyncio.gather(*coroutines)
|
|
344
|
+
|
|
345
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
346
|
+
"""Get optimizer statistics"""
|
|
347
|
+
stats = self.stats.to_dict()
|
|
348
|
+
|
|
349
|
+
# Add pool stats if available
|
|
350
|
+
if self.coroutine_pool:
|
|
351
|
+
pool_stats = self.coroutine_pool.stats.to_dict()
|
|
352
|
+
stats['pool_stats'] = pool_stats
|
|
353
|
+
|
|
354
|
+
return stats
|
|
355
|
+
|
|
356
|
+
def reset_stats(self):
|
|
357
|
+
"""Reset statistics"""
|
|
358
|
+
self.stats = AsyncStats()
|
|
359
|
+
if self.coroutine_pool:
|
|
360
|
+
self.coroutine_pool.stats = AsyncStats()
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# ==================== Utility Functions ====================
|
|
364
|
+
|
|
365
|
+
def is_coroutine_like(obj: Any) -> bool:
|
|
366
|
+
"""
|
|
367
|
+
Check if object is coroutine-like
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
obj: Object to check
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
True if coroutine-like
|
|
374
|
+
"""
|
|
375
|
+
return (
|
|
376
|
+
asyncio.iscoroutine(obj) or
|
|
377
|
+
isinstance(obj, asyncio.Future) or
|
|
378
|
+
hasattr(obj, '__await__')
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def is_immediately_available(awaitable: Any) -> bool:
|
|
383
|
+
"""
|
|
384
|
+
Check if awaitable result is immediately available
|
|
385
|
+
|
|
386
|
+
Args:
|
|
387
|
+
awaitable: Awaitable to check
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
True if result is available without blocking
|
|
391
|
+
"""
|
|
392
|
+
if isinstance(awaitable, FastFuture):
|
|
393
|
+
return True
|
|
394
|
+
|
|
395
|
+
if isinstance(awaitable, asyncio.Future):
|
|
396
|
+
return awaitable.done()
|
|
397
|
+
|
|
398
|
+
return False
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
async def fast_await(awaitable: Any) -> Any:
|
|
402
|
+
"""
|
|
403
|
+
Fast await with optimization
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
awaitable: Object to await
|
|
407
|
+
|
|
408
|
+
Returns:
|
|
409
|
+
Result
|
|
410
|
+
"""
|
|
411
|
+
# Fast path for FastFuture
|
|
412
|
+
if isinstance(awaitable, FastFuture):
|
|
413
|
+
return awaitable.result()
|
|
414
|
+
|
|
415
|
+
# Fast path for done Future
|
|
416
|
+
if isinstance(awaitable, asyncio.Future) and awaitable.done():
|
|
417
|
+
return awaitable.result()
|
|
418
|
+
|
|
419
|
+
# Regular await
|
|
420
|
+
return await awaitable
|