Comprehensive performance profiling for PraisonAI agents
PraisonAI includes a powerful profiling module for measuring and analyzing agent performance. Profile function execution, API calls, streaming latency, memory usage, and more.
from praisonai.profiler import Profiler, profile# Enable profilingProfiler.enable()# Profile a function@profiledef my_agent_task(): # Your agent code here pass# Profile a block of codewith Profiler.block("agent_initialization"): agent = Agent(instructions="You are helpful")# Get reportProfiler.report()
from praisonai.profiler import Profilerwith Profiler.block("data_processing"): # Code to profile process_data()with Profiler.block("model_inference", category="inference"): result = model.predict(data)
Measure Time To First Token (TTFT) and streaming performance:
Copy
from praisonai.profiler import Profiler, StreamingTracker# Using context managerwith Profiler.streaming("chat_completion") as tracker: for chunk in stream: if tracker._first_token_time is None: tracker.first_token() # Mark TTFT tracker.chunk() process(chunk)# Manual trackingtracker = StreamingTracker("my_stream")tracker.start()for i, chunk in enumerate(response_stream): if i == 0: tracker.first_token() tracker.chunk()tracker.end(total_tokens=150)# Get streaming recordsstreams = Profiler.get_streaming_records()for s in streams: print(f"TTFT: {s.ttft_ms:.2f}ms, Total: {s.total_ms:.2f}ms, Chunks: {s.chunk_count}")
from praisonai.profiler import Profiler# Profile memory for a blockwith Profiler.memory("agent_creation"): agent = Agent(instructions="...", tools=[...])# Get memory recordsmemories = Profiler.get_memory_records()for m in memories: print(f"{m.name}: current={m.current_kb:.1f}KB, peak={m.peak_kb:.1f}KB")# Take a snapshotsnapshot = Profiler.memory_snapshot()print(f"Current: {snapshot['current_kb']:.1f}KB")print(f"Peak: {snapshot['peak_kb']:.1f}KB")
from praisonai.profiler import Profiler# Get overall statisticsstats = Profiler.get_statistics()print(f"P50 (Median): {stats['p50']:.2f}ms")print(f"P95: {stats['p95']:.2f}ms")print(f"P99: {stats['p99']:.2f}ms")print(f"Mean: {stats['mean']:.2f}ms")print(f"Std Dev: {stats['std_dev']:.2f}ms")# Get statistics for specific categoryapi_stats = Profiler.get_statistics(category="api")llm_stats = Profiler.get_statistics(category="llm_call")
from praisonai.profiler import Profiler, profile_detailed# Using decorator@profile_detaileddef heavy_computation(): return sum(i * i for i in range(100000))# Using context managerwith Profiler.cprofile("agent_run") as stats: result = agent.run()# Get cProfile statscprofile_data = Profiler.get_cprofile_stats()for entry in cprofile_data: print(f"Operation: {entry['name']}") print(entry['stats'])
from praisonai.profiler import profile_lines@profile_linesdef detailed_function(): a = expensive_operation_1() # Line timing b = expensive_operation_2() # Line timing return a + b# Get line profile dataline_data = Profiler.get_line_profile_data()
Install line_profiler for full functionality: pip install line_profiler
from praisonai.profiler import profile_imports, time_import# Profile imports in a blockwith profile_imports() as profiler: import pandas import numpy from praisonaiagents import Agent# Get slowest importsslowest = profiler.get_slowest(n=5)for imp in slowest: print(f"{imp.module}: {imp.duration_ms:.2f}ms")# Quick single import timingduration = time_import("torch")print(f"torch import: {duration:.2f}ms")
When profiling is disabled, there is zero performance overhead:
Copy
from praisonai.profiler import Profiler, profileProfiler.disable() # Profiling off@profiledef fast_function(): return 1 + 1# No overhead - decorator is a no-op when disabledfor _ in range(1000000): fast_function() # Full speed