Files
big-qmt/py-client/benchmarks/hotpaths.py

67 lines
2.3 KiB
Python
Raw Normal View History

2026-09-07 21:22:51 +08:00
"""Offline microbenchmarks; run with .venv/Scripts/python benchmarks/hotpaths.py."""
import sys
from datetime import datetime, time
from pathlib import Path
from statistics import median
from timeit import repeat
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from libs.calc import trading_time
from sdk.models import _parse_datetime, _side
from strategy.trend.open import _parse_minutes
def original_date(date, clock):
clock = clock.replace(':', '').zfill(6)
try:
return datetime.strptime(date.replace('-', '') + clock, '%Y%m%d%H%M%S')
except ValueError:
return None
def original_minutes(value):
try:
hour_text, minute_text = value.strip().split(':')
hour, minute = int(hour_text), int(minute_text)
except (TypeError, ValueError):
return None
if not 0 <= hour <= 23 or not 0 <= minute <= 59:
return None
return hour * 60 + minute
def original_trading_time(now):
if now.weekday() >= 5:
return False
return time(9, 30) <= now.time() <= time(11, 30) or time(13) <= now.time() <= time(15)
def measure(name, before, after, number=10000):
assert before() == after(), name
old = median(repeat(before, number=number, repeat=5)) / number
new = median(repeat(after, number=number, repeat=5)) / number
print(f'{name:26} {old * 1e6:10.3f} -> {new * 1e6:10.3f} us {old / new:7.2f}x')
def main():
print(sys.version)
print('Same interpreter, original versus optimized; cache timings are warm.')
now = datetime(2026, 9, 7, 14)
measure('order date', lambda: original_date('20260907', '100000'),
lambda: _parse_datetime('20260907', '100000'))
measure('signal time bound', lambda: original_minutes('9:30'), lambda: _parse_minutes('9:30'))
measure('trading session', lambda: original_trading_time(now), lambda: trading_time(now))
measure('order side', lambda: {'23': 'BUY', '24': 'SELL', '48': 'BUY', '49': 'SELL'}.get(str(23), ''),
lambda: _side(23))
positions = {f'{i:06}.SH': None for i in range(1000)}
codes = list(positions)
signals = [f'{i:06}.SH' for i in range(500, 2500)]
measure('1000 positions/2000 signals', lambda: [c for c in signals if c not in codes],
lambda: [c for c in signals if c not in positions], number=100)
if __name__ == '__main__':
main()