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
13 changes: 3 additions & 10 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
## 2024-03-25 - Pre-compiling Regex in performance-critical loops
**Learning:** Initializing `re` matches inside loops without pre-compiling adds significant overhead. Profiling regex performance specifically in `parse_charge_mult` showed that dynamic matching creates a ~1.5x-2x performance bottleneck over 100k invocations compared to `re.compile()` at the module level.
**Action:** Always extract regex expressions into pre-compiled module-level constants (e.g., `RE_CHARGE`, `RE_XYZ`) instead of defining them inline, especially in frequently called parsing loops.

## 2024-05-18 - Replacing `json` with `orjson` for large datasets
**Learning:** In pipelines handling large datasets via dictionaries containing metadata (e.g. millions of prefixes), `json.dump` and `json.load` can become significant bottlenecks, adding seconds or even minutes to startup and checkpointing phases. `orjson` provides a near drop-in replacement that is 4-10x faster for such operations.
**Action:** When working with large JSON files, especially in a framework requiring frequent disk checkpoints, replace Python's built-in `json` module with `orjson` wrapping `loads`/`dumps` to preserve API compatibility while gaining massive performance boosts.
## 2024-03-29 - ASE Custom JSON encoding vs standard JSON
**Learning:** ASE's custom JSON encoder (`ase.io.jsonio.encode`) will generate dicts with special keys like `__ndarray__` or `__complex__` (e.g. `{"__ndarray__": [[5], "int64", ...]}`). When optimizing JSON deserialization using faster alternatives like `orjson`, it's critical to realize that a normal `json.loads` or `orjson.loads` will deserialize this into a Python dictionary, while ASE's custom `decode` will properly reconstruct the underlying numpy array. Bypassing ASE's decoder without checking for these keys leads to downstream type errors (e.g. `KeyError: '__ndarray__'`).
**Action:** When replacing or wrapping ASE's jsonio with `orjson`, always fall back to ASE's `decode` if the payload string contains `__ndarray__` or `__complex__` markers, to ensure custom objects are correctly reconstructed.
## 2024-07-01 - [Optimizing Pandas DataFrame Iteration]
**Learning:** Iterating over large Pandas DataFrames using `df.iterrows()` is a significant performance bottleneck due to the overhead of wrapping each row in a `Series` object and converting types.
**Action:** When iterating over rows in a DataFrame, convert it to a list of dictionaries first using `df.to_dict('records')`. Remember to treat the resulting row as a standard Python dictionary in downstream code, avoiding methods like `row.to_dict()` that were previously used on `Series` objects.
7 changes: 4 additions & 3 deletions src/lavello_mlips/verify_processed_omol25.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ def main() -> None:
)

logger.info(f"Loaded {len(df)} records from Parquet.")
parquet_by_sha = {row["geom_sha1"]: row for _, row in df.iterrows()}
parquet_by_argone_rel = {row["argonne_rel"]: row for _, row in df.iterrows()}
df_records = df.to_dict("records")
parquet_by_sha = {row["geom_sha1"]: row for row in df_records}
parquet_by_argone_rel = {row["argonne_rel"]: row for row in df_records}
logger.info(f"Loading ExtXYZ file from {args.extxyz} (this may take a moment)...")
all_atoms = read(str(args.extxyz), index=":")
if not isinstance(all_atoms, list):
Expand Down Expand Up @@ -108,7 +109,7 @@ def get_dump_entry(at):
info = dict(at.info)
rel = info.get("argonne_rel")
pq_row = parquet_by_argone_rel.get(rel)
pq_data = pq_row.to_dict() if pq_row is not None else None
pq_data = dict(pq_row) if pq_row is not None else None
return {"xyz": info, "parquet": pq_data}

duplicates = {
Expand Down
Loading