Some code I made compares the time it takes to concatenate strings with "string" + "string":
for(int i = 0; i < 100000000L; i++)
{
    String str2 = str + str;
}
to "string".concat("string"):
for(int i = 0; i < 100000000L; i++)
{
    String str2 = str.concat(str);
}
Where str == "string".
The output I get is consistently similar to this, although the average difference is generally closer to 61 nanoseconds:
String str2 = str + str: 118.57349468 nanoseconds
String str2 = str.concat(str): 52.36809985 nanoseconds
.concatis faster than+by 66.20539483 nanoseconds
This shows that even with the loop and assignment to a new string, .concat is faster than + by a factor of more than two. When I use an even longer string (str == "this is a really really very long string that is very long"), it is faster by about a factor of three. This is especially strange, because if .concat is faster, shouldn't they make + compile to .concat?
My main question is: Why is .concat faster?
Full code, in case you want to run it and experiment with it:
public class TimeCompare
{
    public static void main(String[] args)
    {
        final long times = 100000000L;
        String str = "String";
        long start1 = System.nanoTime();
        for(int i = 0; i < times; i++)
        {
            String str2 = str + str;
        }
        long end1 = System.nanoTime();
        long time1 = end1 - start1;
        System.out.println((double)(time1) / times);
        System.out.println();
        long start2 = System.nanoTime();
        for(int i = 0; i < times; i++)
        {
            String str2 = str.concat(str);
        }
        long end2 = System.nanoTime();
        long time2 = end2 - start2;
        System.out.println((double)(time2) / times);
        System.out.println();
        System.out.println(".concat is faster than \"+\" by " + ((double)(time1 - time2) / times) + " nanoseconds");
    }
}
