from timeit import timeit numBaseClasses = (1, 2, 5, 10, 20, 50, 100) setup = ''' class MetaClass(type): pass class BaseClass: def __init__(self): self.attr = None additionalBases = [type(f'BaseClass{i}', (), {}) for i in range(100)] additionalBasesRec = [] for i in range(100): baseClasses = (additionalBasesRec[i-1],) if i else () additionalBasesRec.append(type(f'BaseClass{i}', baseClasses, {})) noMetaBaseX = { i: type(f'TestClass{i}', (BaseClass, *additionalBases[:i-1]), {})() for i in %(numBaseClasses)s} metaBaseX = { i: MetaClass(f'TestClassMeta{i}', (BaseClass, *additionalBases[:i-1]), {})() for i in %(numBaseClasses)s} noMetaRecBaseX = { i: type(f'TestClassRecBase{i}', (BaseClass, additionalBasesRec[i-1]), {})() for i in %(numBaseClasses)s} metaRecBaseX = { i: MetaClass(f'TestClassMetaRecBase{i}', (BaseClass, additionalBasesRec[i-1]), {})() for i in %(numBaseClasses)s} ''' % {'numBaseClasses': numBaseClasses} stmts = [f'{testDict}[{i}].attr' for testDict in ['noMetaBaseX', 'metaBaseX', 'noMetaRecBaseX', 'metaRecBaseX'] for i in numBaseClasses] number = 10**7 for stmt in stmts: total = timeit(stmt=stmt, setup=setup, number=number) print(f'{total/number:.6e} {stmt}')