Index: Python/pythonrun.c
===================================================================
--- Python/pythonrun.c (revision 59400)
+++ Python/pythonrun.c (working copy)
@@ -501,6 +501,9 @@
/* Cleanup Unicode implementation */
_PyUnicode_Fini();
+
+ /* Report counts of attribute cache hits/misses (if enabled) */
+ PyType_Fini();
/* reset file system default encoding */
if (!Py_HasFileSystemDefaultEncoding) {
Index: Include/object.h
===================================================================
--- Include/object.h (revision 59400)
+++ Include/object.h (working copy)
@@ -373,6 +373,9 @@
PyObject *tp_subclasses;
PyObject *tp_weaklist;
destructor tp_del;
+ /* Unique cache ID per type, assigned when bases change (see
+ mro_internal) */
+ PY_LONG_LONG tp_cache_id;
#ifdef COUNT_ALLOCS
/* these must be last and never explicitly initialized */
Index: Include/pythonrun.h
===================================================================
--- Include/pythonrun.h (revision 59400)
+++ Include/pythonrun.h (working copy)
@@ -141,6 +141,7 @@
PyAPI_FUNC(void) PyBytes_Fini(void);
PyAPI_FUNC(void) PyFloat_Fini(void);
PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
+PyAPI_FUNC(void) PyType_Fini(void);
/* Stuff with no proper home (yet) */
PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *);
Index: fastattr_test_py3k.py
===================================================================
--- fastattr_test_py3k.py (revision 0)
+++ fastattr_test_py3k.py (revision 0)
@@ -0,0 +1,265 @@
+#!/usr/bin/python
+
+import timeit, random, time, sys
+
+MULTIPLIER = 1
+
+
+class A(object):
+ def __init__(self, *args):
+ pass
+
+class B(A): pass
+
+class C(B): pass
+
+class D(C): pass
+
+class E(D): pass
+
+class F(E): pass
+
+class G(F): pass
+
+class H(G):
+ def __init__(self):
+ pass
+
+class I(H): pass
+
+
+def test_init(tmp):
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+ tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__; tmp.__init__
+
+
+def test_class(tmp):
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+ tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__; tmp.__class__
+
+
+def test_has_init(tmp):
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+ hasattr(tmp, '__init__'); hasattr(tmp, '__init__')
+
+
+def test_has_class(tmp):
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+ hasattr(tmp, '__class__'); hasattr(tmp, '__class__')
+
+
+def test_has_intit(tmp):
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+ hasattr(tmp, '__intit__'); hasattr(tmp, '__intit__')
+
+
+def test_has_klass(tmp):
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+ hasattr(tmp, '__klass__'); hasattr(tmp, '__klass__')
+
+
+testclasses = [list, dict, tuple, A, B, C, D, E, F, G, H, I]
+list = list
+dict = dict
+tuple = tuple
+list_inst = list()
+dict_inst = dict()
+tuple_inst = tuple()
+A_inst = A()
+B_inst = B()
+C_inst = C()
+D_inst = D()
+E_inst = E()
+F_inst = F()
+G_inst = G()
+H_inst = H()
+I_inst = I()
+
+if __name__ == '__main__':
+ print('class class.__class__ class.__init__' +
+ ' class().__class__ class().__init__')
+ for cls in testclasses:
+ name = cls.__name__
+ print(name, end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_class(%s)' % name,
+ 'from __main__ import test_class, %s' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_init(%s)' % name,
+ 'from __main__ import test_init, %s' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_class(%s_inst)' % name,
+ 'from __main__ import test_class, %s_inst' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_init(%s_inst)' % name,
+ 'from __main__ import test_init, %s_inst' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print()
+ print()
+
+ print('class hasattr(class,"__class__") hasattr(class,"__init__")' +
+ ' hasattr(class(),"__class__") hasattr(class(),"__init__")')
+ for cls in testclasses:
+ name = cls.__name__
+ print(name, end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_class(%s)' % name,
+ 'from __main__ import test_has_class, %s' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_init(%s)' % name,
+ 'from __main__ import test_has_init, %s' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_class(%s_inst)' % name,
+ 'from __main__ import test_has_class, %s_inst' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_init(%s_inst)' % name,
+ 'from __main__ import test_has_init, %s_inst' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print()
+ print()
+
+ print('class hasattr(class,"__klass__") hasattr(class,"__intit__")' +
+ ' hasattr(class(),"__klass__") hasattr(class(),"__intit__")')
+ for cls in testclasses:
+ name = cls.__name__
+ print(name, end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_klass(%s)' % name,
+ 'from __main__ import test_has_klass, %s' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_intit(%s)' % name,
+ 'from __main__ import test_has_intit, %s' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_klass(%s_inst)' % name,
+ 'from __main__ import test_has_klass, %s_inst' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print(timeit.Timer('test_has_intit(%s_inst)' % name,
+ 'from __main__ import test_has_intit, %s_inst' % name)
+ .timeit(number=100000 * MULTIPLIER), end=' ')
+ sys.stdout.flush()
+
+ print()
+ print()
Property changes on: fastattr_test_py3k.py
___________________________________________________________________
Name: svn:executable
+ *
Index: Objects/object.c
===================================================================
--- Objects/object.c (revision 59400)
+++ Objects/object.c (working copy)
@@ -947,6 +947,7 @@
goto done;
}
+#if 0
/* Inline _PyType_Lookup */
{
Py_ssize_t i, n;
@@ -967,6 +968,9 @@
break;
}
}
+#else
+ descr = _PyType_Lookup(tp, name);
+#endif /* 0 */
Py_XINCREF(descr);
Index: Objects/typeobject.c
===================================================================
--- Objects/typeobject.c (revision 59400)
+++ Objects/typeobject.c (working copy)
@@ -6,6 +6,97 @@
#include