简体   繁体   English

在循环内或循环外声明字符串变量是否有效?

[英]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. 它不会对性能产生任何影响(AFAIK),但是对于语义和敏感性,最好在使用它的范围内声明一个变量。 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. 在循环中声明它们也意味着您不必将它们初始化为null ,这对安全性和可维护性都有好处。

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. 编辑:您正在使用声明的变量作为map.get()方法调用的参数,这在第二个示例中将不起作用,因为变量尚未声明,在第一个示例中它们将为null,这将导致错误取决于地图的实现。

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. 更重要的是使变量的范围尽可能小,并避免null初始化。

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... 第二个选项根本没有意义,甚至因为您无法声明对象(字符串“ actual”)并使用正在使用其自身的方法进行初始化而没有编译……

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. 您可以查看生成的JIT代码,以查看编译后的代码的外观。 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. 我做了一个简单的测试,并使用java vm选项执行了该测试: -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Main.f1 (第二种方法是Main.f2),它会打印本机汇编代码并进行比较都。 There is no difference between these two methods. 这两种方法之间没有区别。 Interestingly it doesn't create any code for the first version assignment ( String actual = null ). 有趣的是,它不会为第一个版本分配创建任何代码( 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. Java字节码略有不同,这里的版本1应该慢一些,因为在循环之前执行了空赋值。 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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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