Asking multiple AI to optimise the same code

As different AIs are implemented differently, they don't all provide the same answer, nor do they consistently outperform one another. The best approach is to use multiple AI and pick the one you like best.
My goal here is not to declare a winner based on one example, but instead to show the variety of answers you can get with different AI.
I asked each AI to
Suggest how to implement this more optimally

private static String formatOffset(int millis) {
    String sign = millis < 0 ? "-" : "+";
    int saveSecs = Math.abs(millis) / 1000;
    int hours = saveSecs / 3600;
    int mins = ((saveSecs / 60) % 60);
    int secs = (saveSecs % 60);
    if (secs == 0) {
        if (mins == 0) {
            return sign + twoDigitString(hours);
        }
        return sign + twoDigitString(hours) + twoDigitString(mins);
    }
    return sign + twoDigitString(hours) + twoDigitString(mins) + twoDigitString(secs);
}

private static String twoDigitString(int value) {
    return Integer.toString(value + 100).substring(1);
}

Gemini 2.5 pro

While Gemini is often my first go-to AI when I have a large code base, it's not the smartest. It does have a large context window, which means I can dump a large context into it without much thought on my part. However, if you have less than about 6,000 lines of context, you might find that o3-pro, o4-mini-high, or Claude 4 gives a better answer. In this case, it offered in about 10 seconds;
private static String formatOffset(int millis) {
    long totalSeconds = Math.abs((long) millis / 1000);
    long hours = totalSeconds / 3600;
    long minutes = (totalSeconds % 3600) / 60;
    long seconds = totalSeconds % 60;

    StringBuilder sb = new StringBuilder();
    sb.append(millis < 0 ? "-" : "+");
    sb.append(String.format("%02d", hours));

    if (minutes > 0 || seconds > 0) {
        sb.append(String.format(":%02d", minutes));
    }
    if (seconds > 0) {
        sb.append(String.format(":%02d", seconds));
    }

    return sb.toString();
}
Not only is this approach slower, but it also fails to achieve the same result, which is even worse. The original format is +HHMMSS without a colon.

OpenAI o3-pro

This is both faster and correct. I couldn't say whether this is faster or slower than Claude's answer without benchmarking it.
However, this model took 10 minutes, which isn't always worth the wait.
private static final String[] TWO_DIGIT = new String[60];
static {
    for (int i = 0; i < TWO_DIGIT.length; i++) {
        TWO_DIGIT[i] = (i < 10 ? "0" : "") + i;
    }
}

static String formatOffset(int millis) {
    int totalSecs = millis / 1_000;
    int abs      = Math.abs(totalSecs);

    int hours   = abs / 3_600;
    int minutes = (abs / 60) % 60;
    int seconds =  abs % 60;

    StringBuilder sb = new StringBuilder(7);          // max “+HHMMSS”
    sb.append(totalSecs < 0 ? '-' : '+')
      .append(TWO_DIGIT[hours]);

    if (seconds != 0 || minutes != 0) {
        sb.append(TWO_DIGIT[minutes]);
        if (seconds != 0) sb.append(TWO_DIGIT[seconds]);
    }
    return sb.toString();     // single String allocation here
}

o4-mini-high

This code is faster than the original and correct, and it only took 9 seconds compared to o3-pro 10 minutes...
private static String formatOffset(int millis) {
    long totalSecs = Math.abs((long) millis) / 1_000;
    int hours = (int) (totalSecs / 3_600);
    int remainder = (int) (totalSecs - hours * 3_600);
    int mins  = remainder / 60;
    int secs  = remainder - mins * 60;

    // Determine length: 1 for sign, 2 for HH, +2 for MM if needed, +2 for SS if needed
    int len = 1 + 2 
            + ((mins != 0 || secs != 0) ? 2 : 0) 
            + ((secs != 0) ? 2 : 0);

    char[] buf = new char[len];
    int pos = 0;
    buf[pos++] = millis < 0 ? '-' : '+';
    buf[pos++] = (char) ('0' + hours / 10);
    buf[pos++] = (char) ('0' + hours % 10);

    if (mins != 0 || secs != 0) {
        buf[pos++] = (char) ('0' + mins / 10);
        buf[pos++] = (char) ('0' + mins % 10);
        if (secs != 0) {
            buf[pos++] = (char) ('0' + secs / 10);
            buf[pos++] = (char) ('0' + secs % 10);
        }
    }
    return new String(buf);
}

Claude 4

This is one of the better answers. I use Claude as a third opinion, as I prefer the answers for o3-pro/o4-mini-high or the larger context window of Gemini 2.5 pro.
private static String formatOffset(int millis) {
    char[] buffer = new char[7]; // Max length: +HHMMSS
    int pos = 0;
    
    // Handle sign
    if (millis < 0) {
        buffer[pos++] = '-';
        millis = -millis;
    } else {
        buffer[pos++] = '+';
    }
    
    int totalSecs = millis / 1000;
    int hours = totalSecs / 3600;
    int mins = (totalSecs % 3600) / 60;
    int secs = totalSecs % 60;
    
    // Always include hours
    buffer[pos++] = (char) ('0' + hours / 10);
    buffer[pos++] = (char) ('0' + hours % 10);
    
    if (mins != 0 || secs != 0) {
        buffer[pos++] = (char) ('0' + mins / 10);
        buffer[pos++] = (char) ('0' + mins % 10);
        
        if (secs != 0) {
            buffer[pos++] = (char) ('0' + secs / 10);
            buffer[pos++] = (char) ('0' + secs % 10);
        }
    }
    
    return new String(buffer, 0, pos);
}

Grok 3 Think

Grok 4 is widely considered to be much better; however, I haven't started subscribing to it yet. It's similar to Gemini in this case, without the introduced bug.
private static String formatOffset(int millis) {
    // Determine the sign and work with absolute value
    String sign = millis < 0 ? "-" : "+";
    int absMillis = Math.abs(millis);
    
    // Directly calculate hours, minutes, and seconds
    int hours = absMillis / 3600000;       // 3600000 ms = 1 hour
    int minutes = (absMillis % 3600000) / 60000; // 60000 ms = 1 minute
    int seconds = (absMillis % 60000) / 1000;    // 1000 ms = 1 second

    // Build the result efficiently using StringBuilder
    StringBuilder sb = new StringBuilder();
    sb.append(sign);
    sb.append(String.format("%02d", hours));
    
    // Include minutes and seconds based on their values
    if (minutes > 0 || seconds > 0) {
        sb.append(String.format("%02d", minutes));
        if (seconds > 0) {
            sb.append(String.format("%02d", seconds));
        }
    }
    
    return sb.toString();
}

Copilot

I use Github Copilot in my IDE for simplicity, rarely using the Microsoft Copilot except for curiosity's sake. It's generally worse than the other options I have tried.
In this case, both GitHub Copilot and Microsoft Copilot gave the same answer.
private static String formatOffset(int millis) {
    Duration d = Duration.ofMillis(millis);
    long totalSecs = d.getSeconds();
    long absSecs   = Math.abs(totalSecs);

    long hours = absSecs / 3600;
    int  mins  = (int) ((absSecs % 3600) / 60);
    int  secs  = (int) (absSecs % 60);

    char sign = totalSecs < 0 ? '-' : '+';

    if (secs == 0) {
        return String.format("%c%02d:%02d", sign, hours, mins);
    }
    return String.format("%c%02d:%02d:%02d", sign, hours, mins, secs);
}
This has multiple bugs, and it's significantly slower.
HOT TAKE It worries me when people say they are using Co-pilot a lot and it makes a big difference, because apart from it's convinence, it's not great IMHO.

Conclusion

Particularly when it comes to non-idiomatic code, e.g. low-latency, AI can struggle as these might not be well represented in their training set. I find I spend the most time creating the prompt with the proper context, so copy-and-pasting the same prompt to multiple AI isn't a big deal, you can pick the answer you like or even combine the results.
For the best outcome for you, I recommend learning from each and writing it from scratch yourself. If you just copy-and-paste the answers you aren't thinking about it and probably deskilling yourself in the process.

Comments

Post a Comment

Popular posts from this blog

Java is Very Fast, If You Don’t Create Many Objects

Hands-On Career: The Evolution of a Java Champion

Demystifying Java Object Sizes: Compact Headers, Compressed Oops, and Beyond