@@ -327,18 +327,6 @@ static unsigned int
327
327
_PyType_ClearCache (PyInterpreterState * interp )
328
328
{
329
329
struct type_cache * cache = & interp -> types .type_cache ;
330
- #if MCACHE_STATS
331
- size_t total = cache -> hits + cache -> collisions + cache -> misses ;
332
- fprintf (stderr , "-- Method cache hits = %zd (%d%%)\n" ,
333
- cache -> hits , (int ) (100.0 * cache -> hits / total ));
334
- fprintf (stderr , "-- Method cache true misses = %zd (%d%%)\n" ,
335
- cache -> misses , (int ) (100.0 * cache -> misses / total ));
336
- fprintf (stderr , "-- Method cache collisions = %zd (%d%%)\n" ,
337
- cache -> collisions , (int ) (100.0 * cache -> collisions / total ));
338
- fprintf (stderr , "-- Method cache size = %zd KiB\n" ,
339
- sizeof (cache -> hashtable ) / 1024 );
340
- #endif
341
-
342
330
// Set to None, rather than NULL, so _PyType_Lookup() can
343
331
// use Py_SETREF() rather than using slower Py_XSETREF().
344
332
type_cache_clear (cache , Py_None );
@@ -4147,6 +4135,24 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
4147
4135
return res ;
4148
4136
}
4149
4137
4138
+ /* Check if the "readied" PyUnicode name
4139
+ is a double-underscore special name. */
4140
+ static int
4141
+ is_dunder_name (PyObject * name )
4142
+ {
4143
+ Py_ssize_t length = PyUnicode_GET_LENGTH (name );
4144
+ int kind = PyUnicode_KIND (name );
4145
+ /* Special names contain at least "__x__" and are always ASCII. */
4146
+ if (length > 4 && kind == PyUnicode_1BYTE_KIND ) {
4147
+ const Py_UCS1 * characters = PyUnicode_1BYTE_DATA (name );
4148
+ return (
4149
+ ((characters [length - 2 ] == '_' ) && (characters [length - 1 ] == '_' )) &&
4150
+ ((characters [0 ] == '_' ) && (characters [1 ] == '_' ))
4151
+ );
4152
+ }
4153
+ return 0 ;
4154
+ }
4155
+
4150
4156
/* Internal API to look for a name through the MRO.
4151
4157
This returns a borrowed reference, and doesn't set an exception! */
4152
4158
PyObject *
@@ -4160,14 +4166,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
4160
4166
struct type_cache_entry * entry = & cache -> hashtable [h ];
4161
4167
if (entry -> version == type -> tp_version_tag &&
4162
4168
entry -> name == name ) {
4163
- #if MCACHE_STATS
4164
- cache -> hits ++ ;
4165
- #endif
4166
4169
assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
4167
- OBJECT_STAT_INC (type_cache_hits );
4170
+ OBJECT_STAT_INC_COND (type_cache_hits , !is_dunder_name (name ));
4171
+ OBJECT_STAT_INC_COND (type_cache_dunder_hits , is_dunder_name (name ));
4168
4172
return entry -> value ;
4169
4173
}
4170
- OBJECT_STAT_INC (type_cache_misses );
4174
+ OBJECT_STAT_INC_COND (type_cache_misses , !is_dunder_name (name ));
4175
+ OBJECT_STAT_INC_COND (type_cache_dunder_misses , is_dunder_name (name ));
4171
4176
4172
4177
/* We may end up clearing live exceptions below, so make sure it's ours. */
4173
4178
assert (!PyErr_Occurred ());
@@ -4195,14 +4200,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
4195
4200
entry -> version = type -> tp_version_tag ;
4196
4201
entry -> value = res ; /* borrowed */
4197
4202
assert (_PyASCIIObject_CAST (name )-> hash != -1 );
4198
- #if MCACHE_STATS
4199
- if (entry -> name != Py_None && entry -> name != name ) {
4200
- cache -> collisions ++ ;
4201
- }
4202
- else {
4203
- cache -> misses ++ ;
4204
- }
4205
- #endif
4203
+ OBJECT_STAT_INC_COND (type_cache_collisions , entry -> name != Py_None && entry -> name != name );
4206
4204
assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
4207
4205
Py_SETREF (entry -> name , Py_NewRef (name ));
4208
4206
}
@@ -4219,24 +4217,6 @@ _PyType_LookupId(PyTypeObject *type, _Py_Identifier *name)
4219
4217
return _PyType_Lookup (type , oname );
4220
4218
}
4221
4219
4222
- /* Check if the "readied" PyUnicode name
4223
- is a double-underscore special name. */
4224
- static int
4225
- is_dunder_name (PyObject * name )
4226
- {
4227
- Py_ssize_t length = PyUnicode_GET_LENGTH (name );
4228
- int kind = PyUnicode_KIND (name );
4229
- /* Special names contain at least "__x__" and are always ASCII. */
4230
- if (length > 4 && kind == PyUnicode_1BYTE_KIND ) {
4231
- const Py_UCS1 * characters = PyUnicode_1BYTE_DATA (name );
4232
- return (
4233
- ((characters [length - 2 ] == '_' ) && (characters [length - 1 ] == '_' )) &&
4234
- ((characters [0 ] == '_' ) && (characters [1 ] == '_' ))
4235
- );
4236
- }
4237
- return 0 ;
4238
- }
4239
-
4240
4220
/* This is similar to PyObject_GenericGetAttr(),
4241
4221
but uses _PyType_Lookup() instead of just looking in type->tp_dict. */
4242
4222
static PyObject *
0 commit comments