我使用 imap_headerinfo()函数进行了一些测试,我对结果感到困惑。
在小邮箱上,获取 30条消息的数据需要 0.5 秒。 在包含大约500封邮件的邮箱上,需要 7 秒才能检索相同数量邮件的数据( 30条消息)。
为什么邮箱的大小与检索单个电子邮件的标题所需的时间有关? 这是正常的吗?
我用这段代码来测试时间:
$time_start = microtime(true);
for ($i=0; $i < 30; $i++) {
message_header[$i] = imap_headerinfo($mbox, $i+1);
}
$time = microtime(true) - $time_start;
编辑:
邮箱位于同一帐户中。
我接受了Christian Gollhardt的建议,并测量了对imap_headerinfo()函数的每次调用。
结果甚至更奇怪!首先,然后每隔22次对imap_headerinfo()函数的调用比其他函数多10000次。示例:第一个呼叫大约需要0.39秒,然后其他20个呼叫大约需要0.0001秒,然后第22个呼叫大约需要0.47秒,然后其他20个呼叫大约需要0.00004,依此类推。
编辑2:
经过一些研究后,还有其他的事情发生了。
如果您使用:
$message_header[$i] = imap_headerinfo($mbox, $i + 1);
每22次呼叫大约需要0.4秒,其他呼叫大约需要 0.0001 秒。
但是,你会期望得到相同的结果:
$message_header[$i] = imap_headerinfo($mbox, 30 - $i);
但是,在这种情况下,每次电话需要 0.2 秒!
这里唯一的区别是,在第二个示例中,标题是以反向消息顺序(从第30个到第1个)检索的,并且由于某种原因,它会极大地影响操作所需的时间。为什么呢?
注意:也在gmail帐户上测试过。数字之间的比例完全相同,所以我猜这与服务器无关。
提前谢谢!
答案 0 :(得分:4)
在查看IMAP module的PHP源代码时,您会发现 imap_headerinfo 函数正在使用 mail_fetchstructure ,这是来自c-client的函数图书馆。
documentation for c-client解释了 mail_fetchstructure 函数的工作方式,如下所示:
此功能可以获取所有结构化信息 (信封,内部日期,RFC 822大小,标志和正文结构) 给定的msgno,在IMAP的情况下,最多为MAPLOOKAHEAD(a IMAP2.H中的参数)后续消息尚未出现在 缓存。如果给定msgno的包络已经完成,则不进行提取 在缓存中。返回此msgno的ENVELOPE和BODY。 BODY可能是NIL,在这种情况下没有信息 关于消息体的结构。
我发现一个IMAP头文件将此前瞻值定义为20,因此第一次调用该函数会导致它从邮箱中获取20个附加消息。这解释了你观察到的每一次22次调用函数所花费的时间比其他所有函数都多的行为。
如果以相反的顺序获取消息,则会导致库首先加载21条消息,这些消息以您在函数调用中指定的消息开头。下一个调用检查所请求的消息是否已经被缓存,这不是因为之前之前加载的消息,因此缓存被丢弃并重复该过程。因此,反向循环中的每个调用最多将加载21条消息。
但是,这并不能真正解释不同邮箱大小的性能差异。 我对这种行为的解释比准确的研究更多猜测:c-client库还预先将消息号映射到它们适当的UID。 IMAP头定义了UID前瞻计数1000.这可以解释一定程度的性能损失,但我不知道为什么这会导致如此大的差异,但这是我目前能够想出的唯一解释
尝试使用1000和2000个邮件的邮箱可能会更好地了解此UID查找是否与它有关。如果是这样,500条消息和1000条消息之间的性能应该显着下降,而2000条消息应该与1000条消息一样慢。使用网络嗅探器检查服务器实际请求的数据也值得一试。不幸的是,我没有适合自己的测试环境。