(06-24-2022, 09:10 PM)Boba TC Wrote: my problem is the value of dt: it is greater than 250ms
Well, for starters, you are only looking at an average time. Each message will have a different size of header data, and take a different amount of time to download. Maybe there are larger headers that are increasing the average.
Also, you are issuing multiple IMAP commands per loop iteration, which is skewing the average, too. One thing you could try is to alter the source code for TIdIMAP4.RetrieveHeader() (or, simply duplicate its logic in your own code) to include requesting the UID in its FETCH command so you don't have to retrieve the UID in a separate command. Oddly, RetrieveHeader() is already setup to parse a UID if one is present, it is simply not requesting a UID (there is a ticket already open for that in Indy's issue tracker: https://github.com/IndySockets/Indy/issues/114). I'll fix that in a future release.
In any case...
(06-24-2022, 09:10 PM)Boba TC Wrote: Meaning that I can only get 4 headers per second - this is unacceptably slow.
IMAP is a complex protocol, and TIdIMAP4 isn't the most efficient implementation, either in terms of command usage or in parsing. Also, there are things that the IMAP protocol supports which your task could benefit from (pipelining, bulk fetching, etc) but which TIdIMAP4 doesn't support at this time.
But, that being said, you are clocking the overall time it takes TIdIMAP4 to send the FETCH commands, the time to receive their replies, and the time to parse those replies. The question is, where is that time actually being spent the most? How fast or slow does the server actually reply? How fast or slow does TIdIMAP4 take to parse? You really need to profile these operations separately to discover where the bottleneck really is.
(06-24-2022, 09:10 PM)Boba TC Wrote: Is there a way to call RetrieveHeader for more than just 1 message at a time?
Unfortunately no. It only supports 1 message at a time.
However, the underlying FETCH command does support requesting a sequence of message numbers at a time, and they will all be included in a single reply (this is actually a TODO item for updating the implementation of TIdIMAP4.RetrieveAllHeaders(), which currently calls RetrieveHeader() in a loop, similar to your example). So, you may have to resort to manually issuing your own FETCH command and parsing the reply.
Another thing to consider - do you really need to download ALL headers at a time? If you are connecting and reconnecting over time, you might consider using TIdIMAP4.SearchMailBox() to limit your download of headers to just new messages arrived since the previous download.


