简体   繁体   中英

Is it efficient to declare the string variable inside the loop or outside the loop?

public void see_following_values_match_with_cache_values(DataTable table){

        String actual = null;
        String expected = null;
        List <Map<String, String>> maps = table.asMaps(String.class, String.class);
        for (Map<String, String> map : maps) {
            actual = map.get(actual);
            expected = map.get(expected);
            ///some processing with actual and expected

        }

    }

Or

public void see_following_values_match_with_cache_values(DataTable table){


        List <Map<String, String>> maps = table.asMaps(String.class, String.class);
        for (Map<String, String> map : maps) {
            String actual = map.get(actual);
            String expected = map.get(expected);
            ///some processing with actual and expected

        }

    }

It won't make any performance difference (AFAIK), but for semantics and sensibility you're better off declaring a variable in the scope where it is used. Here you are only using the variables inside the loop, so therefore you should declare them inside the loop too. Declaring them inside the loop also means you don't have to initialise them to null , which is good for safety and maintainability.

EDIT: You are using the declared variables as arguments to the map.get() method call, this will not work in the second example as the variables have yet to be declared and in the first example they will be null, which cause an error depending on the implementation of the map.

The second version is the way to go.

The reason is not efficiency - the performance differnce of both versions will be negligible, if not zero.

What is much more important is to keep the scope of your variables as small as possible and avoid null initializations.

And don't be afraid of declaring a variable inside a loop. Declaration is not something that happens at runtime ans thus will not slow down the program.

EDIT: As others have noticed, both of your code examples do not make sense, the second one won't even compile. But I guess this is because you have simplified your original code a bit too much.

The 2nd option makes no sense at all and is not even compiling just because you can not declare an object (string "actual") and initialized with a method that is using itself...

you should get an error like:

The local variable actual may not have been initialized

You should use the second one, because it is cleaner and has the same performance. You can look at the generated JIT code to see how the compiled code looks like. I made a simple test and executed it with the java vm options: -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Main.f1 (and Main.f2 for the second method) which prints the native assembler code and compared both. There is no difference between these two methods. Interestingly it doesn't create any code for the first version assignment ( String actual = null ).

A bit different is the Java Bytecode, here version 1 should be a bit slower, because the null assignment is executed before the loop. The following bytecode instructions are present:

 LINENUMBER 18 L0
 ACONST_NULL
 ASTORE 3
L1
 LINENUMBER 19 L1
 ACONST_NULL
 ASTORE 4
L2
 LINENUMBER 20 L2

Code to test:

public static void main(String[] args) {
    List<Map<String, String>> maps = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        f1(maps, "", "");
        f2(maps, "", "");
    }
}

public static void f1(List<Map<String, String>> maps, String expected, String actual) {
    String actual1 = null;
    String expected1 = null;
    for (Map<String, String> map : maps) {
        actual1 = map.get(actual);
        expected1 = map.get(expected);
        x(actual1, expected1);
    }
}
public static void x(String expected, String actual) { } 
public static void f2(List<Map<String, String>> maps, String expected, String actual) {
    for (Map<String, String> map : maps) {
        String actual1 = map.get(actual);
        String expected1 = map.get(expected);
        x(actual1, expected1);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM