javastring

Cost of compile time performance


It appears to me that of the 2 approaches, the first one had performace issues related to string concat and toCharArray. But I was told that both these operations occur at compile time so there is no performance overhead.

If this is true then why are compile time operations not performance overheads ?

private final static char[] DigitTens = {
     ("0000000000"+ "1111111111"+"2222222222"+"3333333333"+"4444444444" //
     +"5555555555"+"6666666666"+"7777777777"+"8888888888"+"9999999999")
      .toCharArray();             
};

VS:

private final static char[] DigitTens = {
    '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
    '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
    '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
    '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
    '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
    '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
    '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
    '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
    '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
    '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
};

Solution

  • The string concatenation expression with the +s is a constant expression and is resolved at compile time (JLS §15.28). However, the toCharArray() call is executed at runtime. Overall, your first snippet is equivalent to this:

    private final static char[] DigitTens;
    
    static {
        DigitTens = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
                .toCharArray();
    }
    

    And your second snippet is equivalent to:

    private final static char[] DigitTens;
    
    static {
        DigitTens = new char[100];
        DigitTens[0] = '0';
        DigitTens[1] = '0';
        ...
        DigitTens[99] = '9';
    }
    

    (You can see this yourself in the bytecode via javap -c)

    Ultimately, don't worry about performance here; you likely won't see a difference. Pick whatever you think is clearer and easier to manage. More often than not the time it takes to compile code is irrelevant, since the compilations stage should really only happen once, after which you'll be dealing with the generated .class files that contain the bytecode.

    I'll also point out that in this specific case, DigitTens[i] is simply i / 10, assuming i is in the range 0-99, inclusive.