Cython是否会将静态键键编译为其哈希值



我发现我正在使用静态字符串非常频繁地和嵌套环中访问python dicts。我猜python需要为每个访问访问串起字符串,这可能会影响性能。

例如:

for d in large_list_of_dicts:
    for d2 in d['trees']:
        v = d2['leaves']

Cython Hash是否将这些静态的弦键(仅一次)重复使用这些哈希值?如果是这样,这可能会大大提高此类循环的性能?

cython在这里不会执行任何魔术:它只会将呼叫委派给PyDict_GetItemWithError-基本上是Python解释器会做的相同的事情(但可能更快)。

>

但是,一个unicode-object(我假设我们在谈论python3-strings)缓存其哈希值(在 PyUnicodeObject.hash-ember字段中),因此只需要一次计算一次 - 这是有道理的,因为unicode-object是不变的,这意味着哈希无法更改。

这是负责哈希计算/缓存的CPYTHON代码:

#define _PyUnicode_HASH(op)                             
(((PyASCIIObject *)(op))->hash)
...
static Py_hash_t
unicode_hash(PyObject *self)
{
    ...
    // if hash already calculated, return cached value
    if (_PyUnicode_HASH(self) != -1)
        return _PyUnicode_HASH(self);
    ...
    // else caclculate hash, cache value, return it
    x = _Py_HashBytes(PyUnicode_DATA(self),
                      PyUnicode_GET_LENGTH(self) * PyUnicode_KIND(self));
    _PyUnicode_HASH(self) = x;
    return x;
}

您可以看到,Cython不需要避免使用哈希结果 - 这种优化已经由Cpython完成。

通过在此处使用Cython,最多可以获胜10-30%,因为它会消除该部分的解释器(例如,请参见此件如此之多) - 不是真的,但总比没有好。

最新更新