java 编译与运行时计算

标签 java enums runtime

我试图理解java中的编译与运行时计算。我有以下内容 枚举

public enum SightSensor{

  NORTH (new MapLocation[]{new MapLocation(0,1), 
                         new MapLocation(0,2),
                         new MapLocation(0,3)}),
  SOUTH (new MapLocation[]{new MapLocation(0,-1), 
                        new MapLocation(0,-2),
                        new MapLocation(0,-3)});

  private final MapLocation[] locs;

  SightSensor(MapLocation[] locs){
    this.locs = locs;
  }

  public static MapLocation[] getLocs(Direction dir){
    if (dir == Direction.NORTH)
      return NORTH.locs;
    if (dir == Direction.SOUTH)
      return SOUTH.locs;
  }
};

换句话说,我想定义一个 Direction 和数组之间的常量映射 map 位置。 (也许这是错误的方法?我是 Java 新手。)现在,如果我 写

MapLocation[] locs = SightSensor.getLocs(Direction.SOUTH_WEST);

在代码的循环内,我发现第一次执行代码时存在成本开销 被调用,对我来说意味着它在运行时以某种方式被计算/实例化。如果相反 我直接编码

MapLocation[] locs = new MapLocation[]{new MapLocation(0,1),
                           new MapLocation(0,2),
                           new MapLocation(0,3)};

没有成本开销。我不明白其中的区别。编译器是否做了一些事情 奇怪的即时计算?

最佳答案

您看到的成本似乎是类加载成本:代码第一次访问类时,类加载器将其二进制文件(.class 文件)加载到内存中。这是一次性成本,对于大多数实际用途来说可以忽略不计。

此外:

Now, if I write ... inside a loop in the code, I find that there is a cost overhead the first time the code is called,

你是如何衡量这个成本的?测量单个操作的时间成本几乎是不可能的。您可以测量执行 xM 次循环所需的时间,然后除以得到摊余成本。然而,测量单个操作很困难:您可能会遇到垃圾收集周期、与线程相关的上下文切换等。此外,JIT(即时)编译器不会在第一次执行语句时启动,因此测量单个操作通常会给您带来比 N 次操作的摊余成本高得多的成本。

FWIW,我会编写 getLocs() 如下:

public static MapLocation[] getLocs(Direction dir) {
  return valueOf(dir.name()).locs;
}

或者,您可以使用 EnumMap 类型的变量替换 SightSensor 枚举:

EnumMap<Direction, MapLocation[]> map = new EnumMap(Direction.class);
map.put(Direction.NORTH, new MapLocation[] {  new MapLocation(0, 1), 
                                              new MapLocation(0, 2),
                                              new MapLocation(0, 3) });
map.put(Direction.NORTH, new MapLocation[] {  new MapLocation(0, -1), 
                                              new MapLocation(0, -2),
                                              new MapLocation(0, -3) });

然后,getLocs() 调用就变成了 map.get(dir)

关于java 编译与运行时计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8705539/

相关文章:

java - 如何求距矩形中心的垂直和水平距离

c# - Ruby - 枚举文件

c# - 如何避免在 C# 中使用枚举重复代码?

algorithm - 二分查找运行时间上限 : Recurrence Relation

sql - 在 SQL Server 执行之前修补过时的 SQL 查询?

java - PMD - 有没有办法跟踪个别开发人员的 PMD 投诉

java - 我需要知道如何让我的程序输出我输入的单词以及使用二维数组重新排列的新单词

java - 相同的 Java 源代码编译为二进制不同的类

java - 在 Java 1.6 中使用不同枚举类型的 String 开关

c++ - 为什么运行时堆栈对象的实例变量与堆对象不同?