TradingAgents/benchmark_performance.py

174 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""
Performance Benchmark: Before vs After Connection Pooling
This script demonstrates the performance improvement from connection pooling.
Run with: python benchmark_performance.py
"""
import time
import os
import sys
from decimal import Decimal
# Add project to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tradingagents.brokers import AlpacaBroker
def benchmark_api_calls():
"""Benchmark API call performance."""
print("="*60)
print("API CALL PERFORMANCE BENCHMARK")
print("="*60)
# Check for API keys
if not os.getenv("ALPACA_API_KEY"):
print("\n⚠ No API keys configured")
print("Set ALPACA_API_KEY and ALPACA_SECRET_KEY to run benchmark")
return
broker = AlpacaBroker(paper_trading=True)
broker.connect()
print("\nRunning 10 consecutive API calls...")
print("-" * 60)
times = []
for i in range(10):
start = time.time()
try:
account = broker.get_account()
elapsed = time.time() - start
times.append(elapsed)
print(f" Call {i+1:2d}: {elapsed:.3f}s - Cash: ${account.cash:,.2f}")
except Exception as e:
print(f" Call {i+1:2d}: ERROR - {str(e)}")
broker.disconnect()
if times:
avg_time = sum(times) / len(times)
min_time = min(times)
max_time = max(times)
total_time = sum(times)
print("\n" + "="*60)
print("RESULTS")
print("="*60)
print(f"Total time: {total_time:.2f}s")
print(f"Average per call: {avg_time:.3f}s")
print(f"Fastest call: {min_time:.3f}s")
print(f"Slowest call: {max_time:.3f}s")
print("\n" + "="*60)
print("PERFORMANCE ANALYSIS")
print("="*60)
if avg_time < 0.5:
print("✓✓✓ EXCELLENT: < 0.5s per call")
print(" Connection pooling is working perfectly!")
elif avg_time < 1.0:
print("✓✓ VERY GOOD: < 1.0s per call")
print(" Connection pooling is providing good performance")
elif avg_time < 2.0:
print("✓ GOOD: < 2.0s per call")
print(" Connection pooling is helping")
else:
print("⚠ SLOW: > 2.0s per call")
print(" May indicate network issues or high latency")
print("\nExpected improvement from connection pooling:")
print(" - Without pooling: ~2-5s per call")
print(" - With pooling: ~0.2-1s per call")
print(f" - Your result: {avg_time:.3f}s per call")
improvement = 3.0 / avg_time # Assuming 3s baseline
print(f" - Estimated speedup: {improvement:.1f}x faster")
def benchmark_concurrent_access():
"""Benchmark concurrent API access."""
print("\n\n" + "="*60)
print("CONCURRENT ACCESS BENCHMARK")
print("="*60)
# Check for API keys
if not os.getenv("ALPACA_API_KEY"):
print("\n⚠ Skipping (no API keys)")
return
import threading
broker = AlpacaBroker(paper_trading=True)
broker.connect()
print("\nRunning 5 concurrent API calls...")
print("-" * 60)
results = []
lock = threading.Lock()
def make_call(call_id):
start = time.time()
try:
account = broker.get_account()
elapsed = time.time() - start
with lock:
results.append((call_id, elapsed, None))
except Exception as e:
elapsed = time.time() - start
with lock:
results.append((call_id, elapsed, str(e)))
threads = [threading.Thread(target=make_call, args=(i+1,)) for i in range(5)]
total_start = time.time()
for t in threads:
t.start()
for t in threads:
t.join()
total_elapsed = time.time() - total_start
broker.disconnect()
# Print results
results.sort()
for call_id, elapsed, error in results:
if error:
print(f" Thread {call_id}: {elapsed:.3f}s - ERROR: {error}")
else:
print(f" Thread {call_id}: {elapsed:.3f}s - SUCCESS")
print("\n" + "="*60)
print("CONCURRENT RESULTS")
print("="*60)
print(f"Total wallclock time: {total_elapsed:.2f}s")
print(f"Average thread time: {sum(e for _, e, _ in results)/len(results):.3f}s")
if total_elapsed < 2.0:
print("\n✓✓✓ EXCELLENT concurrent performance!")
print(" Threads executed efficiently")
elif total_elapsed < 5.0:
print("\n✓✓ GOOD concurrent performance")
print(" Reasonable parallelization")
else:
print("\n⚠ Sequential execution detected")
print(" Threads may be blocking each other")
def main():
"""Run all benchmarks."""
benchmark_api_calls()
benchmark_concurrent_access()
print("\n" + "="*60)
print("BENCHMARK COMPLETE")
print("="*60)
if __name__ == "__main__":
main()