←
examples/performance/profiling_example.py
#!/usr/bin/env python3
"""
Profiling minimal d'un workload Catnip avec cProfile.
Objectif:
- donner un point de départ concret pour le futur guide de performance
- profiler le chemin Python -> parse -> execute
- sortir un top cumulé lisible sans dépendance externe
"""
from __future__ import annotations
import cProfile
import io
import pstats
import click
from catnip import Catnip
EXPECTED_RESULT = 28008000
CODE = """
sum_to = (n, acc=0) => {
if n <= 0 { acc }
else { sum_to(n - 1, acc + n) }
}
mix = (n) => {
total = 0
for i in range(1, n + 1) {
total = total + (i * 3) - (i // 2)
}
total + sum_to(n)
}
mix(4000)
"""
@click.command()
@click.option("-r", "--repeat", default=12, show_default=True, help="Cycles parse+execute à profiler.")
@click.option("-t", "--top", default=20, show_default=True, help="Nombre de fonctions à afficher.")
def main(repeat: int, top: int) -> None:
"""Profile un workload représentatif Catnip (parse + execute)."""
profiler = cProfile.Profile()
def workload() -> None:
for _ in range(repeat):
cat = Catnip(vm_mode="on", optimize=1)
cat.parse(CODE)
result = cat.execute()
if result != EXPECTED_RESULT:
raise click.ClickException(f"unexpected result: {result}")
profiler.enable()
workload()
profiler.disable()
stream = io.StringIO()
stats = pstats.Stats(profiler, stream=stream).sort_stats("cumtime")
stats.print_stats(top)
click.echo("Catnip profiling example")
click.echo("=" * 80)
click.echo(f"repeat={repeat}, optimize=1, vm_mode=on")
click.echo("workload=parse + execute d'un mix boucle + récursion terminale")
click.echo("\nTop cumulative time")
click.echo("-" * 80)
click.echo(stream.getvalue())
if __name__ == "__main__":
main()