| """Line-by-line profiling of transform_app_train_inputs (étape 4). |
| |
| Uses line_profiler programmatically — no @profile decorator pollution in |
| the source. Builds 100 realistic payloads from application_train.csv, loads |
| the training-time category artefacts, and runs transform_app_train_inputs |
| in a loop wrapped by LineProfiler. |
| |
| Usage: |
| uv run python scripts/profile_transform_lines.py |
| uv run python scripts/profile_transform_lines.py --n 500 |
| uv run python scripts/profile_transform_lines.py --output profiling/lines.txt |
| """ |
|
|
| from __future__ import annotations |
|
|
| import argparse |
| import logging |
| import random |
| import sys |
| from pathlib import Path |
|
|
| REPO_ROOT = Path(__file__).resolve().parents[1] |
| if str(REPO_ROOT) not in sys.path: |
| sys.path.insert(0, str(REPO_ROOT)) |
|
|
| logger = logging.getLogger("scripts.profile_transform_lines") |
| logging.basicConfig(level=logging.INFO, format="%(message)s") |
|
|
|
|
| def main() -> int: |
| parser = argparse.ArgumentParser(description=__doc__) |
| parser.add_argument("--n", type=int, default=100, |
| help="number of transform calls to profile (default: 100)") |
| parser.add_argument("--seed", type=int, default=42) |
| parser.add_argument("--output", type=Path, |
| default=REPO_ROOT / "profiling" / "profile_transform_lines.txt", |
| help="text dump path (default: ./profiling/profile_transform_lines.txt)") |
| args = parser.parse_args() |
|
|
| from line_profiler import LineProfiler |
|
|
| from api import settings |
| from api.inputs_transform import ( |
| load_binary_mappings, |
| load_categories, |
| transform_app_train_inputs, |
| ) |
| from scripts.seed_traffic import APP_TRAIN_PATH, build_payloads |
|
|
| known_categories = load_categories(settings.APP_TRAIN_CATEGORIES_PATH) |
| binary_mappings = load_binary_mappings(settings.APP_TRAIN_BINARY_MAPPINGS_PATH) |
|
|
| rng = random.Random(args.seed) |
| payloads = build_payloads(APP_TRAIN_PATH, n_known=args.n, n_unknown=0, rng=rng) |
| |
| |
| payloads = [{k: v for k, v in p.items() if k != "SK_ID_CURR"} for p in payloads] |
|
|
| def driver(): |
| for payload in payloads: |
| transform_app_train_inputs(payload, known_categories, binary_mappings) |
|
|
| lp = LineProfiler() |
| lp.add_function(transform_app_train_inputs) |
| wrapped = lp(driver) |
| wrapped() |
| |
| lp.print_stats(output_unit=1e-3) |
| args.output.parent.mkdir(parents=True, exist_ok=True) |
| with open(args.output, "w", encoding="utf-8") as fh: |
| lp.print_stats(stream=fh, output_unit=1e-3) |
| logger.info("Line-profile dump saved to %s", args.output) |
| return 0 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |
|
|