有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java声明变量但不初始化它会提高性能吗?

我目前正在学习计算机科学,想了解一切,所以我在书中注意到,人们声明一个变量int x;,然后在声明的正下方初始化它,例如

int x;
x = 0;

我想知道这是否对内存或编译代码的效率有积极的影响


共 (6) 个答案

  1. # 1 楼答案

    除非您有一个非常不寻常的编译器,否则这不会改变编译代码中的任何内容

  2. # 3 楼答案

    除了代码的可读性,没有任何变化:编译器应该知道第一个赋值发生在其他地方,并在那里执行赋值

    一般来说,您应该更喜欢将初始化和赋值结合起来,除非在少数情况下,第一次赋值应该发生在声明变量的内部作用域中,例如在do/while循环内赋值,并在循环完成后使用:

    bool found; // No assignment
    do {
        found = false;
        ...
        if (...) {
            found = true;
        }
        ...
    } while (!finished(someCondition));
    
  3. # 4 楼答案

    以下是Java的故事:

    对于简单类:

    public class MyClass {
        public static void main(String... args)
        {
            int x = 0;
        }
    }
    

    public class MyClass {
        public static void main(String... args)
        {
            int x;
            x = 0;
        }
    }
    

    我们在这两种情况下得到相同的字节码:

    enter image description here

    因此,因为两者之间没有区别。作为参考,这是通过以下方式生成的:

    javap -c MyClass.class
    
  4. # 5 楼答案

    一般来说,如果变量的赋值范围与声明的范围相同,则不会有性能(甚至代码)差异。如今,任何现代编译器都应该能够进行这种简单的优化。(如果没有,扔掉它,买一个像样的。)

    如果在定义范围内进行任何赋值之前,将变量的地址传递给函数并在那里进行初始化,则会产生极小的差异。但是你确实需要好的、高性能的代码来注意这一点,所以你应该首先关注可读性和安全性(永远不要使用单元化内存),并且只有当你测量到初始化有关的性能问题时,才回到这个点

  5. # 6 楼答案

    I currently learning computer science and want to understand everything

    你来对地方了

    if that does something positive to memory or efficiency of the compiled code

    没有,但你怎么知道?经验数据,兄弟

    花点时间研究一下我的编译器的这两个中间输出。这里有一个传说:最左边的列不有趣,忽略它。下一列显示源文件名(example2.c)的名称或从源文件生成的可执行机器指令(0000 55)。原始来源的线条显示在四个星号的位置。它与编译时生成的相应程序集输出交错。指令助记符和参数显示在可执行指令的右侧。在这两个例子之间来回看看,你会发现这两个例子中的说明是相同的

    我使用gccgcc -c -g -Wa,-ahl=example.s example.c)创建了这些示例

    首先,使用“sane”初始化:

       6                with_init:                                         
       7                .LFB0:
       8                    .file 1 "example2.c"                           
       1:example2.c    **** 
       2:example2.c    **** int with_init()                                
       3:example2.c    **** {
       9                    .loc 1 3 0
      10                    .cfi_startproc                                 
      11 0000 55            pushq   %rbp                                   
      12                .LCFI0:
      13                    .cfi_def_cfa_offset 16                         
      14                    .cfi_offset 6, -16                             
      15 0001 4889E5        movq    %rsp, %rbp                             
      16                .LCFI1:
      17                    .cfi_def_cfa_register 6                        
       4:example2.c    ****     int x = 0;                                 
      18                    .loc 1 4 0
      19 0004 C745FC00      movl    $0, -4(%rbp)                           
      19      000000   
       5:example2.c    ****     
       6:example2.c    ****     return x;                                  
      20                    .loc 1 6 0
      21 000b 8B45FC        movl    -4(%rbp), %eax                         
       7:example2.c    **** }
      22                    .loc 1 7 0
      23 000e 5D            popq    %rbp                                   
      24                .LCFI2:
      25                    .cfi_def_cfa 7, 8                              
      26 000f C3            ret
    

    现在你提出了一个更“有趣”的案例:

       6                later_init:
       7                .LFB0:
       8                    .file 1 "example.c"
       1:example.c     ****
       2:example.c     **** int later_init()
       3:example.c     **** {
       9                    .loc 1 3 0
      10                    .cfi_startproc
      11 0000 55            pushq   %rbp
      12                .LCFI0:
      13                    .cfi_def_cfa_offset 16
      14                    .cfi_offset 6, -16
      15 0001 4889E5        movq    %rsp, %rbp
      16                .LCFI1:
      17                    .cfi_def_cfa_register 6
       4:example.c     ****     int x;
       5:example.c     ****
       6:example.c     ****     x = 0;
      18                    .loc 1 6 0
      19 0004 C745FC00      movl    $0, -4(%rbp)
      19      000000
       7:example.c     ****
       8:example.c     ****     return x;
      20                    .loc 1 8 0
      21 000b 8B45FC        movl    -4(%rbp), %eax
       9:example.c     **** }
      22                    .loc 1 9 0
      23 000e 5D            popq    %rbp
      24                .LCFI2:
      25                    .cfi_def_cfa 7, 8
      26 000f C3            ret
    

    没什么区别

    编辑:我以前没有看到java标签。在这种情况下,可以说更为直接:

    $ cat example.java 
    
    class SOComparison
    {
    
        public static int with_init()
        {
            int x = 0;
    
            return x;
        }
    
        public static int later_init()
        {
            int x;
    
            x = 0;
    
            return x;
        }
    
    }
    $ javap -c SOComparison
    Compiled from "example.java"
    class SOComparison {
      SOComparison();
        Code:
           0: aload_0       
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return        
    
      public static int with_init();
        Code:
           0: iconst_0      
           1: istore_0      
           2: iload_0       
           3: ireturn       
    
      public static int later_init();
        Code:
           0: iconst_0      
           1: istore_0      
           2: iload_0       
           3: ireturn       
    }