1
\$\begingroup\$

I am creating a miniature bulk email sender. I am using Postfix on Ubuntu with JavaMail. Here is the key part of the code:

public static void main(final String[] args){
    final Connection selectConnection = DriverManager.getConnection(prop.getProperty("select_connection"));
    final Statement stmt = selectConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    stmt.setFetchSize(Integer.MIN_VALUE);
    ResultSet rs = stmt.executeQuery("SELECT email FROM emails");
    while(rs.next()){
        recipient = rs.getString("email");
        session = rs.getString("code");
        unsubscribeParameters = "s="+session+"&c="+campaign+"&r="+recipient;
        openedParameters = "s="+session+"&c="+campaign;
        sendEmail(recipient, campaign, html.replace("unsubscribeParameters", unsubscribeParameters).replace("openedParameters", openedParameters), properties);
    }
}
private static void sendEmail(final String recipient, final String campaign, final String html, final Properties properties){
    final String verp = campaign+"="+recipient.replace("@", "+") + "@example.com";
    properties.put("mail.smtp.from", verp);
    final Session session = Session.getDefaultInstance(properties);
    final MimeMessage message = new MimeMessage(session);
    try {
        message.setFrom(new InternetAddress(SENDER_ADDRESS, SENDER_NAME));
        message.setSubject(subject);
        final MimeBodyPart textPart = new MimeBodyPart();
        textPart.setContent(plainText, "text/plain");
        final MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(html, "text/html");
        final Multipart mp = new MimeMultipart("alternative");
        mp.addBodyPart(textPart);
        mp.addBodyPart(htmlPart);
        message.setContent(mp);
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
        Transport.send(message);
    } catch (final Exception | OutOfMemoryError e) {
        //handle errors
    }
}

Right now, I'm getting about 7 emails a second on a 512 MB RAM box, 1 core processor, and a 20 GB SSD disk. Does anyone see any ways to speed this up? Is it possible?

\$\endgroup\$
  • \$\begingroup\$ How fast is your network connectivity? SSD or RAM is moot if your network speed is slow. \$\endgroup\$ – h.j.k. Dec 6 '15 at 3:44
  • \$\begingroup\$ @h.j.k. Not sure exactly how fast it is. Seems to be fast enough. My question was more geared towards the specific code in question - is there any way to speed it up via refactoring? \$\endgroup\$ – John Roberts Dec 6 '15 at 4:11
2
\$\begingroup\$

It looks like you are sending almost the same message multiple times. I see at least two possible speed improvements.

  • The most likely bottleneck is the actual email sending process, which is outside of your program, an overhead for every single message sent. You could reduce that overhead by putting multiple recipients in BCC, if possible. As you noted in comments, ISPs might consider messages with a large number of recipients. If you stay within reasonable limits, and you're not in fact spamming, you can hopefully convince them to allow it. (This did happen to me once, and my ISP was reasonable.)

  • Another minor improvement can be, instead of creating a new message from scratch for each recipient, you could create a single message object once, and replace the recipient and other variable parts in it.

The code is too compactly written. I suggest to use your IDE to reformat it nicely.

The try block covers a lot of code. It seems you could move some code of it. That would be better, to clarify the sensitive parts where something might go wrong.

Catching Exception is not recommended. It's recommended to catch the most specific exception that might be thrown.

It's a bit strange to catch OutOfMemoryError. This is not something a program can recover from gracefully. You don't share the piece of code handling the exception, but I doubt it would be much different from not handling that at all.

\$\endgroup\$
  • \$\begingroup\$ It's actually "almost" the same message. If you notice at the end of my main method, you will see that I am doing a replace on the html to insert the session code for the URLs. The multiple recipients point is well stated - my hesitation with that is I've read that ISPs consider messages with lots of recipients "spammy". \$\endgroup\$ – John Roberts Dec 6 '15 at 15:10
  • \$\begingroup\$ I rewrote my points with more details, and also addressed your question related to ISPs. \$\endgroup\$ – janos Dec 6 '15 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.