Python: email.message_from_string在大数据邮件内容中的性能

0 投票
1 回答
1743 浏览
提问于 2025-04-16 03:09

最近我在玩Python的imaplib和email模块。我尝试使用这些模块发送和接收大邮件(大部分数据在邮件正文中,而不是附件)。

不过,我发现一个问题:当我从邮件服务器下载大邮件(大约8MB以上)并使用“email.message_from_string()”方法格式化它们时,这个方法的耗时似乎非常长(对于一封16MB的邮件,平均大约需要300-310秒)。注意:发送这样大的邮件并不会花太多时间,大约40秒左右。而且,所有数据都在邮件正文中——没有附件。如果我把同样的邮件下载为附件,整个操作只需30-40秒。

我做的事情是:

buf = []
t, d = mailacct.search(None, 'SUBJECT', subj)
for num in d:
    t, msg = mailacct.fetch(num, '(RFC822)')

    for resp in msg:
        if isinstance(resp, tuple):
            buf.append(email.message_from_string(resp[1])

我分别测量了代码的每个部分的时间。mailacct.search和mailacct.fetch对于一封16MB的邮件大约都在30-40秒内完成。使用email.message_from_string(resp[1])这一行大约需要280-300秒。

我还是个Python新手。那么我在上面的代码中做得很低效吗?还是问题出在email.message_from_string()这个方法上,可能是实现得不够好?或者说,邮件正文本来就不应该包含大量数据,所以表现不佳?

* 编辑 *
附加信息:我使用了imaplib.IMAP4_SSL来创建IMAP连接。我先用imaplib.append()将消息上传到邮箱。我使用随机生成的二进制数据作为负载。

1 个回答

1

好的,我自己查了一下,研究了邮件模块的源代码。邮件解析函数(parse())在email/parser.py文件里,这个函数就是在调用email.message_from_string()时,实际处理邮件内容的地方。它似乎是把字符串分成8192字节一块一块地解析,这就是为什么处理大数据时会花很长时间。我修改了代码,让它一次性读取和处理整个字符串,这样处理大邮件的时间大大缩短了。

我在想,最开始设置成每次处理8192字节,是为了应对特别特别大的字符串吗?有没有比直接修改邮件模块源代码更好的方法呢?

撰写回答