Performance Tip: Use String.intern() correctly.

Overview

String.intern() can be used to improve memory consumption. However its benifit is limited to specific situations, and can be misused as a general performance method when it doesn't help.

Don't: Use String.intern() on compile-time constants

Compile time constants are automatically placed in the String literal pool.

From SchemaSymbols
    public static final String ELT_GROUP                = "group".intern();
    public static final String ELT_IMPORT               = "import".intern();
    public static final String ELT_INCLUDE              = "include".intern();
The String literals will be placed in the String pool anyway. Calling intern() on them adds complexity to the code, and overhead but adds no benefit.

Is there a side effect?

There is the side effect that using .intern() on a compile time literal stops it being inlined into another Compile time literal. Sometimes this is desirable, however when it is not is adds a performance overhead.
e.g.
String s = ELT_IMPORT + " " + ELT_GROUP;
Without the .intern() method on the constants this string would be evaluated at compile time. In this case, it will be evaluated at runtime, every time it is called.

Using intern() to improve performance

If the possible values of String is limited and largely unchanging, intern() can be used like a pseudo-enum.

From Class.searchFields(Field[] fields, String name)
String internedName = name.intern();
for (int i = 0; i < fields.length; i++) {
     if (fields[i].getName() == internedName) {
Every possible field name will be in the String literal pool already so calling intern() has little cost, but it does allow all the String comparisons to use == instead of equals() as would be normal practice.

Comments

Popular posts from this blog

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

System wide unique nanosecond timestamps

Unusual Java: StackTrace Extends Throwable