bpo-38045: Improve the performance of _decompose() in enum.py (GH-16483)
* Improve the performance of _decompose() in enum.py Co-Authored-By: Brandt Bucher <brandtbucher@gmail.com>
This commit is contained in:
parent
e563a155be
commit
0b41a922f9
33
Lib/enum.py
33
Lib/enum.py
|
@ -861,28 +861,20 @@ def _decompose(flag, value):
|
||||||
# _decompose is only called if the value is not named
|
# _decompose is only called if the value is not named
|
||||||
not_covered = value
|
not_covered = value
|
||||||
negative = value < 0
|
negative = value < 0
|
||||||
# issue29167: wrap accesses to _value2member_map_ in a list to avoid race
|
|
||||||
# conditions between iterating over it and having more pseudo-
|
|
||||||
# members added to it
|
|
||||||
if negative:
|
|
||||||
# only check for named flags
|
|
||||||
flags_to_check = [
|
|
||||||
(m, v)
|
|
||||||
for v, m in list(flag._value2member_map_.items())
|
|
||||||
if m.name is not None
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
# check for named flags and powers-of-two flags
|
|
||||||
flags_to_check = [
|
|
||||||
(m, v)
|
|
||||||
for v, m in list(flag._value2member_map_.items())
|
|
||||||
if m.name is not None or _power_of_two(v)
|
|
||||||
]
|
|
||||||
members = []
|
members = []
|
||||||
for member, member_value in flags_to_check:
|
for member in flag:
|
||||||
|
member_value = member.value
|
||||||
if member_value and member_value & value == member_value:
|
if member_value and member_value & value == member_value:
|
||||||
members.append(member)
|
members.append(member)
|
||||||
not_covered &= ~member_value
|
not_covered &= ~member_value
|
||||||
|
if not negative:
|
||||||
|
tmp = not_covered
|
||||||
|
while tmp:
|
||||||
|
flag_value = 2 ** _high_bit(tmp)
|
||||||
|
if flag_value in flag._value2member_map_:
|
||||||
|
members.append(flag._value2member_map_[flag_value])
|
||||||
|
not_covered &= ~flag_value
|
||||||
|
tmp &= ~flag_value
|
||||||
if not members and value in flag._value2member_map_:
|
if not members and value in flag._value2member_map_:
|
||||||
members.append(flag._value2member_map_[value])
|
members.append(flag._value2member_map_[value])
|
||||||
members.sort(key=lambda m: m._value_, reverse=True)
|
members.sort(key=lambda m: m._value_, reverse=True)
|
||||||
|
@ -890,8 +882,3 @@ def _decompose(flag, value):
|
||||||
# we have the breakdown, don't need the value member itself
|
# we have the breakdown, don't need the value member itself
|
||||||
members.pop(0)
|
members.pop(0)
|
||||||
return members, not_covered
|
return members, not_covered
|
||||||
|
|
||||||
def _power_of_two(value):
|
|
||||||
if value < 1:
|
|
||||||
return False
|
|
||||||
return value == 2 ** _high_bit(value)
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Improve the performance of :func:`enum._decompose` in :mod:`enum`. Patch by hongweipeng.
|
Loading…
Reference in New Issue