One thing you could do is change the focus of the question to the underlying mail software. For instance, if I wanted to send a ton of emails, I would use any language to write them out in BSMTP format, which basically looks like simple SMTP client commands. Something like:
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: Me <[email protected]>
To: You <[email protected]>
Subject: test email
This is the body of the test email I'm sending
.
Then I would feed the BSMTP files through exim:
cat *.bsmtp | exim -bS
This essentially removes the delay in sending the emails from you program and places the burden on exim (which as an MTA is better equipped to handle it).
Once you get the basics, there are a ton of things you can modify to make more efficient. For instance, if your emails aren't customized, you can pre-optimize by putting all recipients to the same domain into the same BSMTP file:
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
RCPT TO:<[email protected]>
RCPT TO:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: Me <[email protected]>
To: Me <[email protected]>
Subject: test email
This is the body of the test email I'm sending
.
You also then get a ton of wiggle room in how you optimize the MTA itself to send the mail (for instance, it'll automatically handle parallel deliveries, deliveries of email to the same mail server down the same TCP connection, etc).
With respect to doing it in code, we used to have a drop in perl library that helped us do this stuff. Essentially you fed it the emails and the addresses and it would fork off calls to the mail server as needed. It was configurable in how many parallel sessions it would allow, and it also monitored the load on the server and would throttle back if the load crossed a user-configurable threshold.