11#!/usr/bin/env python3
22# -*- coding: utf-8 -*-
33"""
4+ Micro-benchmarks for spatialmath: base functions and classes for SO(3),
5+ SE(3), quaternions and twists, plus a NumPy baseline. Run from a checkout::
6+
7+ python benchmarks/benchmark_smtb.py
8+
9+ The output starts with a summary of the machine and package versions, so a
10+ pasted table is self-describing.
11+
412Created on Fri Apr 10 14:22:36 2020
513
614@author: Peter Corke
715"""
816
9-
17+ import os
18+ import platform
19+ import subprocess
1020import timeit as _timeit
21+
22+ import numpy as np
1123from ansitable import ANSITable , Column
1224
25+ import spatialmath
26+
1327N = 10_000
1428REPEATS = 5
1529
1630table = None
1731
1832
33+ def cpu_info () -> str :
34+ """Best-effort, portable one-line CPU description
35+
36+ :return: CPU name and core count, plus clock speed if available
37+ :rtype: str
38+
39+ No new hard dependency: psutil is used for clock speed only if already
40+ installed. Some platforms (e.g. Apple Silicon) don't expose a single
41+ meaningful clock speed, so a missing or nonsensical reading is omitted.
42+ """
43+ system = platform .system ()
44+ name = None
45+
46+ if system == "Darwin" :
47+ try :
48+ name = subprocess .check_output (
49+ ["sysctl" , "-n" , "machdep.cpu.brand_string" ], text = True
50+ ).strip ()
51+ except Exception :
52+ pass
53+ elif system == "Linux" :
54+ try :
55+ with open ("/proc/cpuinfo" ) as f :
56+ for line in f :
57+ if line .lower ().startswith ("model name" ):
58+ name = line .split (":" , 1 )[1 ].strip ()
59+ break
60+ except Exception :
61+ pass
62+ elif system == "Windows" :
63+ name = platform .processor () or None
64+
65+ if not name :
66+ name = platform .processor () or platform .machine () or "unknown CPU"
67+
68+ info = f"{ name } ({ os .cpu_count () or '?' } cores)"
69+
70+ try :
71+ import psutil
72+
73+ freq = psutil .cpu_freq ()
74+ # real clock speeds are hundreds to thousands of MHz; some platforms
75+ # report bogus single-digit values instead of raising
76+ if freq and freq .max and freq .max > 100 :
77+ info += f", { freq .max :.0f} MHz"
78+ except Exception :
79+ pass
80+
81+ return info
82+
83+
84+ def print_machine_summary () -> None :
85+ print (f"CPU: { cpu_info ()} " )
86+ print (f"OS: { platform .platform ()} " )
87+ print (f"Python: { platform .python_version ()} " )
88+ print (f"numpy: { np .__version__ } " )
89+ print (f"spatialmath: { spatialmath .__version__ } " )
90+ print (f"Timing: min of { REPEATS } repeats x { N } calls" )
91+
92+
1993def new_table ():
2094 return ANSITable (
2195 Column ("Operation" , headalign = "^" ),
@@ -41,6 +115,8 @@ def section(title):
41115 table = new_table ()
42116
43117
118+ print_machine_summary ()
119+
44120# ------------------------------------------------------------------------- #
45121transforms_setup = '''
46122from spatialmath import SE3
0 commit comments