Skip to content

Commit

Permalink
tools.target: use slots for Channel and User types
Browse files Browse the repository at this point in the history
This can save some significant memory when Sopel is in many and/or large
channels. For example, without this patch (in bytes):

- Size of empty channel: 1200
- Size of channel with 100 users: 84560
- Size of channel with 1000 users: 817944

And with this patch (also in bytes):

- Size of empty channel: 680
- Size of channel with 100 users: 72608
- Size of channel with 1000 users: 705304

An empty channel is reduced by nearly half, and channels with some
significant user count can be reduced by some 10-15%.

These values were calculated using `Pympler.asizeof.asizeof()`, in a
simple test script:

    from sopel.tools import Identifier, target
    from pympler.asizeof import asizeof

    c = target.Channel(Identifier('#Sopel'))

    print('Size of empty channel:', asizeof(c))

    for n in range(1, 100):
        name = 'user{}'.format(n)
        c.add_user(
            target.User(
                Identifier(name)
                name,
                'some.example.org'
            )
        )

    print('Size of channel with 100 users:', asizeof(c))

    for n in range(101, 1000):
        name = 'user{}'.format(n)
        c.add_user(
            target.User(
                Identifier(name),
                name,
                'some.example.org'
            )
        )

    print('Size of channel with 1000 users:', asizeof(c))
  • Loading branch information
dgw committed Dec 31, 2021
1 parent d36a19d commit 3ca95e5
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions sopel/tools/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class User:
:param str user: the user's local username ("user" in `user@host.name`)
:param str host: the user's hostname ("host.name" in `user@host.name`)
"""
__slots__ = (
'nick', 'user', 'host', 'channels', 'account', 'away',
)

def __init__(self, nick, user, host):
assert isinstance(nick, Identifier)
self.nick = nick
Expand Down Expand Up @@ -59,6 +63,10 @@ class Channel:
:param name: the channel name
:type name: :class:`~.tools.Identifier`
"""
__slots__ = (
'name', 'users', 'privileges', 'topic', 'modes', 'last_who', 'join_time',
)

def __init__(self, name):
assert isinstance(name, Identifier)
self.name = name
Expand Down

0 comments on commit 3ca95e5

Please sign in to comment.