【问题标题】:Is it efficient to declare the string variable inside the loop or outside the loop?在循环内或循环外声明字符串变量效率高吗?
【发布时间】:2016-06-15 19:21:33
【问题描述】:
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

        }

    }

或者

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

        }

    }

【问题讨论】:

    标签: java performance space-complexity


    【解决方案1】:

    它不会产生任何性能差异(AFAIK),但为了语义和敏感性,您最好在使用它的范围内声明一个变量。这里你只在循环内使用变量,因此你也应该在循环内声明它们。在循环中声明它们也意味着您不必将它们初始化为null,这有利于安全性和可维护性。

    编辑:您正在使用声明的变量作为 map.get() 方法调用的参数,这在第二个示例中不起作用,因为变量尚未声明,在第一个示例中它们将为 null,这会根据地图的实现而导致错误。

    【讨论】:

      【解决方案2】:

      第二个版本是要走的路。

      原因不是效率 - 两个版本的性能差异即使不是零也可以忽略不计。

      更重要的是保持变量的范围尽可能小并避免null 初始化。

      不要害怕在循环中声明一个变量。声明不是在运行时发生的,因此不会减慢程序的速度。

      编辑:正如其他人所注意到的,您的两个代码示例都没有意义,第二个甚至无法编译。但我想这是因为您将原始代码简化了太多。

      【讨论】:

        【解决方案3】:

        第二个选项完全没有意义 甚至没有编译只是因为你不能声明一个对象(字符串“实际”)并用一个使用自身的方法初始化......

        你应该得到如下错误:

        局部变量actual可能没有初始化

        【讨论】:

          【解决方案4】:

          您应该使用第二个,因为它更干净并且具有相同的性能。您可以查看生成的 JIT 代码以了解编译代码的外观。我做了一个简单的测试并使用 java vm 选项执行它:-Xcomp -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Main.f1(以及第二种方法的 Main.f2)打印本机汇编代码并比较两者。这两种方法没有区别。有趣的是,它不会为第一个版本分配 (String actual = null) 创建任何代码。

          Java Bytecode 有点不同,这里的版本 1 应该会慢一些,因为 null 赋值是在循环之前执行的。存在以下字节码指令:

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

          要测试的代码:

          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);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-02-06
            • 1970-01-01
            • 2014-06-15
            • 1970-01-01
            • 2016-12-05
            • 1970-01-01
            • 2012-02-02
            相关资源
            最近更新 更多