mirror of
https://github.com/python/cpython.git
synced 2025-12-23 09:19:18 +00:00
Merge 1c59358f7f into f9704f1d84
This commit is contained in:
commit
10fe1994e4
4 changed files with 47 additions and 5 deletions
|
|
@ -114,6 +114,7 @@ extern Py_ssize_t _Py_dict_lookup_threadsafe_stackref(PyDictObject *mp, PyObject
|
|||
|
||||
extern int _PyDict_GetMethodStackRef(PyDictObject *dict, PyObject *name, _PyStackRef *method);
|
||||
|
||||
extern Py_ssize_t _PyDict_LookupIndexAndValue(PyDictObject *, PyObject *, PyObject **);
|
||||
extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *);
|
||||
extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key);
|
||||
|
||||
|
|
|
|||
|
|
@ -2346,10 +2346,9 @@ dict_unhashable_type(PyObject *key)
|
|||
}
|
||||
|
||||
Py_ssize_t
|
||||
_PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
|
||||
_PyDict_LookupIndexAndValue(PyDictObject *mp, PyObject *key, PyObject **value)
|
||||
{
|
||||
// TODO: Thread safety
|
||||
PyObject *value;
|
||||
assert(PyDict_CheckExact((PyObject*)mp));
|
||||
assert(PyUnicode_CheckExact(key));
|
||||
|
||||
|
|
@ -2359,7 +2358,14 @@ _PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
|
|||
return -1;
|
||||
}
|
||||
|
||||
return _Py_dict_lookup(mp, key, hash, &value);
|
||||
return _Py_dict_lookup(mp, key, hash, value);
|
||||
}
|
||||
|
||||
Py_ssize_t
|
||||
_PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
|
||||
{
|
||||
PyObject *value; // discarded
|
||||
return _PyDict_LookupIndexAndValue(mp, key, &value);
|
||||
}
|
||||
|
||||
/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
|
||||
|
|
|
|||
|
|
@ -355,6 +355,21 @@ static int function_kind(PyCodeObject *code);
|
|||
static bool function_check_args(PyObject *o, int expected_argcount, int opcode);
|
||||
static uint32_t function_get_version(PyObject *o, int opcode);
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
static void
|
||||
maybe_enable_deferred_ref_count(PyObject *op)
|
||||
{
|
||||
if (!_Py_IsOwnedByCurrentThread(op)) {
|
||||
// For module level variables that are heavily used from multiple
|
||||
// threads, deferred reference counting provides good scaling
|
||||
// benefits. The downside is that the object will only be deallocated
|
||||
// by a GC run.
|
||||
PyUnstable_Object_EnableDeferredRefcount(op);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, PyObject *name)
|
||||
{
|
||||
|
|
@ -369,7 +384,8 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P
|
|||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
index = _PyDict_LookupIndex(dict, name);
|
||||
PyObject *value;
|
||||
index = _PyDict_LookupIndexAndValue(dict, name, &value);
|
||||
assert (index != DKIX_ERROR);
|
||||
if (index != (uint16_t)index) {
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR,
|
||||
|
|
@ -384,6 +400,9 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P
|
|||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
|
||||
return -1;
|
||||
}
|
||||
#ifdef Py_GIL_DISABLED
|
||||
maybe_enable_deferred_ref_count(value);
|
||||
#endif
|
||||
write_u32(cache->version, keys_version);
|
||||
cache->index = (uint16_t)index;
|
||||
specialize(instr, LOAD_ATTR_MODULE);
|
||||
|
|
@ -1264,7 +1283,6 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
specialize_load_global_lock_held(
|
||||
PyObject *globals, PyObject *builtins,
|
||||
|
|
@ -1284,7 +1302,12 @@ specialize_load_global_lock_held(
|
|||
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);
|
||||
goto fail;
|
||||
}
|
||||
#ifdef Py_GIL_DISABLED
|
||||
PyObject *value;
|
||||
Py_ssize_t index = _PyDict_LookupIndexAndValue((PyDictObject *)globals, name, &value);
|
||||
#else
|
||||
Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name);
|
||||
#endif
|
||||
if (index == DKIX_ERROR) {
|
||||
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
|
||||
goto fail;
|
||||
|
|
@ -1305,6 +1328,9 @@ specialize_load_global_lock_held(
|
|||
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
|
||||
goto fail;
|
||||
}
|
||||
#ifdef Py_GIL_DISABLED
|
||||
maybe_enable_deferred_ref_count(value);
|
||||
#endif
|
||||
cache->index = (uint16_t)index;
|
||||
cache->module_keys_version = (uint16_t)keys_version;
|
||||
specialize(instr, LOAD_GLOBAL_MODULE);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
# > echo "0" | sudo tee /sys/devices/system/cpu/cpufreq/boost
|
||||
#
|
||||
|
||||
import copy
|
||||
import math
|
||||
import os
|
||||
import queue
|
||||
|
|
@ -214,6 +215,14 @@ def instantiate_dataclass():
|
|||
for _ in range(1000 * WORK_SCALE):
|
||||
obj = MyDataClass(x=1, y=2, z=3)
|
||||
|
||||
|
||||
@register_benchmark
|
||||
def deepcopy():
|
||||
x = {'list': [1, 2], 'tuple': (1, None)}
|
||||
for i in range(40 * WORK_SCALE):
|
||||
copy.deepcopy(x)
|
||||
|
||||
|
||||
def bench_one_thread(func):
|
||||
t0 = time.perf_counter_ns()
|
||||
func()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue