gpt4 book ai didi

java - 为什么在静态上下文中访问实例化字段比在 JAVA 中访问实例化上下文更快

转载 作者:行者123 更新时间:2023-12-01 16:16:16 27 4
gpt4 key购买 nike

我一直认为,从实例化方法/函数访问实例化字段应该会提高一些性能,因为数据应该“更本地可用”(我知道这可能取决于系统和 JVM),而不是从静态上下文。请参阅说明我的观点的代码:

public class Lecture
{
public static void main(String[] args)
{
hold h1 = new hold();
long start1 = System.currentTimeMillis();
h1.accessOOPs();
long end1 = System.currentTimeMillis();
System.out.println("OOPS: "+ (end1 - start1));

hold h2 = new hold();
long start2 = System.currentTimeMillis();
hold.accessStatic(h2);
long end2 = System.currentTimeMillis();
System.out.println("Static (same class): "+ (end2 - start2));

hold h3 = new hold();
long start3 = System.currentTimeMillis();
accessStatic(h3);
long end3 = System.currentTimeMillis();
System.out.println("Static (different class): "+ (end3 - start3));
}
public static void accessStatic(hold h)
{
for (int i=0;i<h.vars.length;i++)
h.vars[i] = i;
for (int i : h.vars)
h.var1 += i;
for (int i: h.vars)
h.name += i;
}
}
class hold
{
int var1;
int vars[] = new int[10000];
String name;
public void accessOOPs()
{
for (int i=0;i<vars.length;i++)
vars[i] = i;
for (int i : vars)
var1 += i;
for (int i: vars)
name += i;
}
public static void accessStatic(hold h)
{
for (int i=0;i<h.vars.length;i++)
h.vars[i] = i;
for (int i : h.vars)
h.var1 += i;
for (int i: h.vars)
h.name += i;
}
}

在代码中,我有 3 个定时示例,我在其中访问/修改简单对象中的属性。第一个示例调用对象中的实例方法,因此理论上所有属性的访问速度应该更快,因为它们与该方法位于相同的上下文中。第二个调用对象类中的静态函数,并每次使用点运算符访问属性。我的假设是这会更慢。第三个示例重复与第二个示例相同的操作,但这次是在单独的类中进行的。我对收到的时间感到非常困惑:

示例运行 1:

  • 哎呀:135
  • 静态(同级):130
  • 静态(不同类别):120

示例运行 2:

  • 哎呀:137
  • 程序(同级):135
  • 程序(不同类别):128

当方法位于单独的类中时,OOP 方法始终击败静态方法,但我不明白为什么当静态方法位于同一个类中时,它会击败实例方法。虽然只有微小的差距,但非常一致。这是否只是因为静态实现正在缓存对正在访问的对象的引用而发生?如果发生这种情况,那么我会认为静态方法是否在单独的类中并不重要,所以我完全感到困惑。谁能回答为什么静态方法没有明显变慢?

最佳答案

您的 h3 变量未传递给任何调用,因此第三次调用中对 h2 进行的计算与之前对 h1/h2 的计算不同。

在进行时序测试时,您应该只测量预热的代码(因为 JIT 编译器会稍微改变性能)。如果您修复使用 h3 并在循环内运行主代码,您会发现运行之间的差异很小,我得到的最后一次运行是

OOPS: 56
Static (same class): 56
Static (different class): 50

您可以看到 accessOOP 和 accessStatic 的字节码结构非常相似,使用:

javap -v hold.class > hold.log
javap -v Lecture.class > lecture.log

在 JDK14 中,它们的长度都是 114 项,仅字段/索引位置不同,WINDIFF.EXE 中显示了差异

Bytecode diffs accessOOPs vs accessStatic

关于java - 为什么在静态上下文中访问实例化字段比在 JAVA 中访问实例化上下文更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62382274/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com