当前位置: 首页 > 知识库问答 >
问题:

访问实例字段比声明局部变量需要更长的时间?[副本]

程峻
2023-03-14

我在看一个关于基本Java游戏编程的视频,看到了这段代码

private void render() {
    BufferStrategy bs = getBufferStrategy();
    if (bs == null){
        createBufferStrategy(3);
        return;
    }
}

在我看来,通过在render方法之外声明引用“bs”,代码运行得更快,这样就不会在每一帧都重新创建它,但我自己实际测试了它,发现情况恰恰相反。

package test;

public class tm {
    static String s;

    public static void loop1(){
        s = "hi";
    }

    public static void loop2(){
        String d;
        d = "hi";
    }
    public static void main(String[] args) {

        long x1 = System.nanoTime();
        for(int i = 0;i<100000;i++)
            loop1();
        long x2 = System.nanoTime();
        for(int i = 0;i<100000;i++)
            loop2();
        long x3 = System.nanoTime();

        System.out.println(x2-x1);
        System.out.println(x3-x2);
    }
}

运行了几次之后,就可以明显看出loop1平均花费的时间要长一个数量级。仅仅访问一个实例字段比创建一个新变量需要更长的时间,这似乎有悖于直觉。是我错过了什么还是就这么简单?如何才能了解哪些等效操作需要更长的时间,从而更好地优化代码?

1937701
284818

2036061
599144

3189017
675694

1971058
608125

有几次跑步。我的基准不正确吗?

共有1个答案

籍星汉
2023-03-14

设置一个局部变量要快得多,特别是当它什么都不做的时候。您正在计时的是JIT检测和优化代码所需的时间。您会发现,如果您将循环的长度增加一倍,它不会花费更多的时间。

当您设置一个静态变量时,JIT很难优化它。

 类似资料:
  • 我得到了一个问题,对内部类的局部变量访问需要声明为final。从方法createGrids()->“”中,i是一个需要声明为final的局部变量。我不知道为什么,我在字段中添加了final,但它并不起作用。 //略

  • 我知道这个话题听起来像是重复的,但我并不是想在这里调试这个问题,而是想绕过它。 我的程序应该做的是:对于文件夹中的每个文件,创建一个新按钮。如果您单击此按钮,请输入您刚输入的文件夹的名称。 现在我遇到的问题是,“fileName”变量需要放在final中,因为Java提供的是对象的指针,而不是值本身。但如果我这样做,则只会为任何按钮发送最后选择的文件名。

  • 我正在尝试让一个按钮将其值与其他变量进行比较。在onClick方法中,我收到一个错误,说变量在内部类中被访问,需要声明为最终变量。问题是变量应该被更改,所以我无法使其成为最终变量。我如何解决这个问题?这是我的代码:

  • 局部变量使用关键字 def 来声明,其只在声明它的地方可见 . 局部变量是 Groovy 语言的一个基本特性. 例子 13.2 . 使用局部变量 def dest = "dest" task copy(type: Copy) { form "source" into dest }

  • 问题内容: 在lambda中,局部变量需要是最终变量,而实例变量则不需要。为什么这样? 问题答案: 字段和局部变量之间的根本区别在于,当JVM创建lambda实例时,将复制局部变量。另一方面,字段可以自由更改,因为对它们的更改也将传播到外部类实例(它们的范围是整个外部类,如Boris所指出的)。 考虑到匿名类,闭包和Labmdas的最简单方法是从可变范围的角度来看。想象一个为传递给闭包的所有局部变

  • 我正在尝试创建一个布局为“是”或“否”的警报对话框。我想通过单击“否”按钮而不是对话框视图来关闭该对话框。Disclose() 有错误。 这是我的密码。