diff options
| author | Rapptz <[email protected]> | 2018-09-24 22:06:49 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2018-09-24 22:19:42 -0400 |
| commit | 95d8bb2e8551e61d1603f588dbed053344fada80 (patch) | |
| tree | d32a40f9a8a5d4244558be90bf4a2ad8b69be9ca /discord/member.py | |
| parent | Change internal role storage in Guild to a dict instead of a list. (diff) | |
| download | discord.py-95d8bb2e8551e61d1603f588dbed053344fada80.tar.xz discord.py-95d8bb2e8551e61d1603f588dbed053344fada80.zip | |
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.
Diffstat (limited to 'discord/member.py')
| -rw-r--r-- | discord/member.py | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/discord/member.py b/discord/member.py index e407546a..009a2104 100644 --- a/discord/member.py +++ b/discord/member.py @@ -136,10 +136,6 @@ class Member(discord.abc.Messageable, _BaseUser): Attributes ---------- - roles: List[:class:`Role`] - A :class:`list` of :class:`Role` that the member belongs to. Note that the first element of this - list is always the default '@everyone' role. These roles are sorted by their position - in the role hierarchy. joined_at: `datetime.datetime` A datetime object that specifies the date and time in UTC that the member joined the guild for the first time. @@ -154,7 +150,7 @@ class Member(discord.abc.Messageable, _BaseUser): The guild specific nickname of the user. """ - __slots__ = ('roles', 'joined_at', 'status', 'activity', 'guild', 'nick', '_user', '_state') + __slots__ = ('_roles', 'joined_at', 'status', 'activity', 'guild', 'nick', '_user', '_state') def __init__(self, *, data, guild, state): self._state = state @@ -187,15 +183,7 @@ class Member(discord.abc.Messageable, _BaseUser): return ch def _update_roles(self, data): - # update the roles - self.roles = [self.guild.default_role] - for role_id in map(int, data['roles']): - role = self.guild.get_role(role_id) - if role is not None: - self.roles.append(role) - - # sort the roles by hierarchy since they can be "randomised" - self.roles.sort() + self._roles = utils.SnowflakeList(map(int, data['roles'])) def _update(self, data, user=None): if user: @@ -249,6 +237,24 @@ class Member(discord.abc.Messageable, _BaseUser): color = colour @property + def roles(self): + """A :class:`list` of :class:`Role` that the member belongs to. Note + that the first element of this list is always the default '@everyone' + role. + + These roles are sorted by their position in the role hierarchy. + """ + result = [] + g = self.guild + for role_id in self._roles: + role = g.get_role(role_id) + if role: + result.append(role) + result.append(g.default_role) + result.sort() + return result + + @property def mention(self): """Returns a string that mentions the member.""" if self.nick: |