Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
## 2025-05-15 - Regex Alternation Performance
**Learning:** Replacing multiple `re.search()` calls for simple literals with a single `re.compile(r'literal1|literal2|...')` regex was ~50% SLOWER in Python.
**Insight:** Python's `re` module likely uses optimized string search algorithms (like Boyer-Moore) for simple literal patterns, which are faster than the state machine overhead of a large alternation regex.
**Action:** Prefer multiple simple `re.search()` calls over complex alternations when patterns are mostly literals. Only use combined regex when tokenization/parsing requires strictly ordered matching or when patterns share complex prefixes.

## 2025-05-20 - Pre-compiling Regex in Loops
**Learning:** `re.findall(pattern, string)` recompiles (or retrieves from cache) the pattern on every call. In high-frequency functions called inside loops (like complexity estimation), this overhead adds up.
**Action:** Always pre-compile regexes (`re.compile`) into module-level or class-level constants if they are used repeatedly, especially in tight loops or recursive functions.
## 2024-05-18 - [Optimized Asyncio Event Loop Handling]
**Learning:** `asyncio.as_completed()` yields coroutines. Calling `loop.run_until_complete(coro)` for each yielded coroutine inside a synchronous for-loop is a major anti-pattern. It repeatedly blocks the main thread, stops the event loop, and restarts it for every single task, completely defeating concurrency.
**Action:** Always wrap concurrent task aggregation in a single overarching async function (e.g., `async def run_all()`) where you `await` the individual tasks, and call `loop.run_until_complete(run_all())` exactly once to keep the event loop running smoothly.
Comment on lines +1 to +3
22 changes: 15 additions & 7 deletions evolutia/evolutia_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,13 +530,21 @@ def generate_variations_async(
asyncio.set_event_loop(loop)

valid_variations = []
for coro in tqdm(asyncio.as_completed(async_tasks), total=len(async_tasks), desc="Generando"):
try:
result = loop.run_until_complete(coro)
if result:
valid_variations.append(result)
except Exception as e:
logger.error(f"Excepción no manejada en async worker: {e}")

# ⚡ Bolt Optimization: Wrap task aggregation in a single async coroutine
# Previously, loop.run_until_complete() was called inside the for-loop.
# This blocked the event loop on each iteration, causing overhead and defeating concurrency.
# Running the loop once with `run_all()` awaits all tasks concurrently.
async def run_all():
for coro in tqdm(asyncio.as_completed(async_tasks), total=len(async_tasks), desc="Generando"):
try:
result = await coro
Comment on lines +539 to +541
if result:
valid_variations.append(result)
except Exception as e:
logger.error(f"Excepción no manejada en async worker: {e}")

loop.run_until_complete(run_all())

logger.info(f"Generación async completada. {len(valid_variations)} variaciones exitosas.")
return valid_variations
Expand Down