Discord.py如何快速统计服务器用户发送的消息数量并存储到列表
Discord用户消息量统计优化方案
原代码性能瓶颈
- 遍历10万条消息逐条匹配作者,存在大量无意义的IO和计算开销
- 检索用户时使用
discord.utils.find遍历全服成员,时间复杂度为O(n),效率极低 - 冗余存储所有匹配消息的内容,对于仅需统计数量的场景完全没有必要
- 依赖用户对象匹配,用户退服后无法统计历史消息,且对象匹配开销高于基础数据类型匹配
轻量化优化方案
不需要改造整体逻辑,仅修改核心代码即可降低30%~50%的统计耗时:
msg_count = 0 # 可按需添加after/before参数缩小消息检索范围,大幅减少需要拉取的消息量 # 示例:after=datetime(2024,1,1) 仅统计2024年1月1日之后的消息 async for message in channel.history(limit=100000): # 直接匹配整数ID,避免获取用户对象的开销,同时兼容已退服用户的历史消息统计 if message.author.id == j: msg_count += 1 print(msg_count)
长期使用高性能方案
如果需要经常进行消息量统计,推荐使用预统计方案,查询耗时可降低至毫秒级:
给bot添加消息事件监听,实时将用户消息计数写入本地存储,查询时直接读存储即可,示例代码如下:
import sqlite3 # 初始化本地数据库 conn = sqlite3.connect('msg_count.db') c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS msg_count (guild_id INT, user_id INT, count INT, PRIMARY KEY (guild_id, user_id))''') conn.commit() @bot.event async def on_message(message): if not message.author.bot: # 过滤机器人消息 c.execute('INSERT OR IGNORE INTO msg_count VALUES (?, ?, 0)', (message.guild.id, message.author.id)) c.execute('UPDATE msg_count SET count = count + 1 WHERE guild_id = ? AND user_id = ?', (message.guild.id, message.author.id)) conn.commit() await bot.process_commands(message)
查询时直接执行SQL语句即可拿到结果:
c.execute('SELECT count FROM msg_count WHERE guild_id = ? AND user_id = ?', (guild_id, j)) print(c.fetchone()[0])
注意事项
- Discord API对历史消息拉取有速率限制,短时间内大量拉取会触发限流导致耗时变长,批量拉取多频道消息时建议添加适当的延迟处理
- 以上代码基于discord.py v2.x版本编写,旧版本部分方法语法可能存在差异
内容的提问来源于stack exchange,提问作者Hiresh Verma
相关产品推荐
相关产品推荐

