History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: IDEADEV-23749
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Normal Normal
Assignee: Bas Leijdekkers
Reporter: Peter Lawrey
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
IDEA: Development

"Concatenation with empty string" inspection should not warn on compile time constants

Created: 12 Nov 07 17:33   Updated: 21 Feb 08 21:15
Component/s: Code Analysis. Inspection
Fix Version/s: Selena 7.0.3

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown

Build: 7,531
Fixed in build: 7,719


 Description  « Hide
It notes: "Such concatenation is unnecessary and inefficient, particularly when used as an idiom for formatting non-String objects or primitives into Strings. "

However in the following test you can see that using ""+X is many times faster that String.valueOf(X) as the compiler can convert the string at compile time. Perhaps it should read "Such concatenation is necessary and efficient ..."

Why is it use at all, to avoid defining two constants, one as a char and the other as a String.

""+DECIMAL_PLACE time=151659 ns
String.valueOf(DECIMAL_PLACE) time=9442612 ns
""+DECIMAL_PLACE time=44825 ns
String.valueOf(DECIMAL_PLACE) time=2457340 ns
""+DECIMAL_PLACE time=30193 ns
String.valueOf(DECIMAL_PLACE) time=1334597 ns

the code is

private static final char DECIMAL_PLACE = '.';
    private static final int REPEATS = 10000;

    public static void main(String... args) {
        doTest();
        doTest();
        doTest();
    }

    private static void doTest() {
        long start = System.nanoTime();
        String s = null;
        for (int i = 0; i < REPEATS; i++)
            s = "" + DECIMAL_PLACE;
        long time = System.nanoTime() - start;
        assert ".".equals(s);
        start = System.nanoTime();
        for (int i = 0; i < REPEATS; i++)
            s = String.valueOf(DECIMAL_PLACE);
        assert ".".equals(s);
        long time2 = System.nanoTime() - start;
        System.out.println("\"\"+DECIMAL_PLACE time=" + time + " ns");
        System.out.println("String.valueOf(DECIMAL_PLACE) time=" + time2 + " ns");
    }


 All   Comments   Work Log   Change History      Sort Order:
Bas Leijdekkers - 12 Nov 07 18:32
For constants the concatenation with empty string is indeed better, because the conversion can be done at compile time. For runtime values the inspection is correct:
private static final char DECIMAL_PLACE = '.';
	private static final int REPEATS = 10000;

	public static void main(String... args) {
		doTest(DECIMAL_PLACE);
		doTest(DECIMAL_PLACE);
		doTest(DECIMAL_PLACE);
	}

	private static void doTest(char c) {
		long start = System.nanoTime();
		String s = null;
		for (int i = 0; i < REPEATS; i++)
			s = "" + c;
		long time = System.nanoTime() - start;
		assert ".".equals(s);
		start = System.nanoTime();
		for (int i = 0; i < REPEATS; i++)
			s = String.valueOf(c);
		assert ".".equals(s);
		long time2 = System.nanoTime() - start;
		System.out.println("\"\"+DECIMAL_PLACE time=" + time + " ns");
		System.out.println("String.valueOf(DECIMAL_PLACE) time=" + time2 + " ns");
	}

I guess this inspection should not warn on compile time constants.