Change internal representation of roles in Member and Emoji.

Introduce a new internal type, SnowflakeList, which has better memory
footprint over a regular list or set of roles. It is suspected that
there will be a 9x reduction of memory for every Emoji instance and a
48 byte saving per Member instance. However, these savings will
probably only be evident on larger bots.

As a consequence of this change, Member.roles is now computed lazily.

Currently I am not sure if I want to do the initial sorting on the
SnowflakeList for Member, as this comes with a O(n log n) cost when
creating a Member for little purpose since SnowflakeList.has is not
overly relied on. If CPU time becomes an issue this might change.
This commit is contained in:
Rapptz
2018-09-24 22:06:49 -04:00
parent 3d03dbc451
commit 95d8bb2e85
5 changed files with 67 additions and 21 deletions

View File

@ -415,9 +415,10 @@ class GuildChannel:
default = self.guild.default_role
base = Permissions(default.permissions.value)
roles = member.roles
# Apply guild roles that the member has.
for role in member.roles:
for role in roles:
base.value |= role.permissions.value
# Guild-wide Administrator -> True for everything
@ -436,7 +437,13 @@ class GuildChannel:
except IndexError:
remaining_overwrites = self._overwrites
member_role_ids = set(map(lambda r: r.id, member.roles))
# not sure if doing member._roles.get(...) is better than the
# set approach. While this is O(N) to re-create into a set for O(1)
# the direct approach would just be O(log n) for searching with no
# extra memory overhead. For now, I'll keep the set cast
# Note that the member.roles accessor up top also creates a
# temporary list
member_role_ids = {r.id for r in roles}
denies = 0
allows = 0