java编译时与运行时计算
我试图理解java中编译计算与运行时计算的区别。我有以下几点 枚举 换句话说,我想在一个方向和一个数组之间定义一个常量映射 地图位置。(也许这是一种错误的方法?我是Java新手。)现在,如果我 写 在代码中的一个循环中,我发现在第一次编写代码时存在开销 调用,这对我来说意味着它在运行时以某种方式被计算/实例化。如果相反 我只是直接编码java编译时与运行时计算,java,enums,runtime,Java,Enums,Runtime,我试图理解java中编译计算与运行时计算的区别。我有以下几点 枚举 换句话说,我想在一个方向和一个数组之间定义一个常量映射 地图位置。(也许这是一种错误的方法?我是Java新手。)现在,如果我 写 在代码中的一个循环中,我发现在第一次编写代码时存在开销 调用,这对我来说意味着它在运行时以某种方式被计算/实例化。如果相反 我只是直接编码 MapLocation[] locs = new MapLocation[]{new MapLocation(0,1),
MapLocation[] locs = new MapLocation[]{new MapLocation(0,1),
new MapLocation(0,2),
new MapLocation(0,3)};
没有开销。我不明白有什么区别。编译器做了些什么
奇怪的即时计算
编译器会做一些奇怪的即时计算吗
是的,Java运行时确实在运行时使用统计信息来优化代码:
没什么奇怪的
这也可能是相关的:
就个人而言,我认为您应该编写尽可能容易阅读的代码,而不必担心优化。加速可能并不显著
编译器会做一些奇怪的即时计算吗
是的,Java运行时确实在运行时使用统计信息来优化代码:
没什么奇怪的
这也可能是相关的:
就个人而言,我认为您应该编写尽可能容易阅读的代码,而不必担心优化。加速可能并不显著。您看到的成本似乎是类加载成本:代码第一次访问类时,类加载程序将其二进制(.class文件)加载到内存中。这是一个一次性成本,在大多数实际情况下可以忽略不计 此外: 现在,如果我写。。。在代码中的一个循环中,我发现在第一次调用代码时存在开销 你是如何衡量这一成本的?要衡量一次操作的时间成本几乎是不可能的。您可以通过一个循环测量执行xM过程所需的时间,然后可以进行分割以获得摊余成本。然而,度量单个操作是困难的:您可能会得到垃圾收集周期、与线程相关的上下文切换等。此外,JIT(实时)编译器不会在第一次执行语句时启动,因此度量单个操作通常会给您带来比N个操作的摊余成本高得多的成本 FWIW,我将写
getLocs()
,如下所示:
public static MapLocation[] getLocs(Direction dir) {
return valueOf(dir.name()).locs;
}
或者,您可以使用EnumMap类型的变量替换SightSensor enum:
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) });
EnumMap map=新的EnumMap(Direction.class);
地图放置(方向北,新地图位置[]{新地图位置(0,1),
新地图位置(0,2),
新映射位置(0,3)};
地图放置(方向北,新地图位置[]{新地图位置(0,-1),
新映射位置(0,-2),
新映射位置(0,-3)};
然后,
getLocs()
调用就变成了map.get(dir)
您看到的成本似乎是类加载成本:代码第一次访问类时,类加载程序将其二进制(.class文件)加载到内存中。这是一个一次性成本,在大多数实际情况下可以忽略不计
此外:
现在,如果我写。。。在代码中的一个循环中,我发现在第一次调用代码时存在开销
你是如何衡量这一成本的?要衡量一次操作的时间成本几乎是不可能的。您可以通过一个循环测量执行xM过程所需的时间,然后可以进行分割以获得摊余成本。然而,度量单个操作是困难的:您可能会得到垃圾收集周期、与线程相关的上下文切换等。此外,JIT(实时)编译器不会在第一次执行语句时启动,因此度量单个操作通常会给您带来比N个操作的摊余成本高得多的成本
FWIW,我将写getLocs()
,如下所示:
public static MapLocation[] getLocs(Direction dir) {
return valueOf(dir.name()).locs;
}
或者,您可以使用EnumMap类型的变量替换SightSensor enum:
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) });
EnumMap map=新的EnumMap(Direction.class);
地图放置(方向北,新地图位置[]{新地图位置(0,1),
新地图位置(0,2),
新映射位置(0,3)};
地图放置(方向北,新地图位置[]{新地图位置(0,-1),
新映射位置(0,-2),
新映射位置(0,-3)};
然后,
getLocs()
调用就变成了map.get(dir)
这不是一个真正的答案,而是一个提示:使getLocs
非静态,只需返回当前枚举的locs
:
public MapLocation[] getLocs(){
return locs;
}
然后调用someDir.getLocs()
,而不是SightSensor.getLocs(someDir)
这样可以避免枚举枚举的所有成员。这不是一个真正的答案,而是一个提示:使
getLocs
非静态,只返回当前枚举的locs
:
public MapLocation[] getLocs(){
return locs;
}
然后调用someDir.getLocs()
,而不是SightSensor.getLocs(someDir)
这样,您就不必枚举枚举的所有成员。您能解释一下您是如何衡量成本开销的吗?此外,您的示例也无法编译;您需要在
getLocs
中使用某种else语句,因为现在存在没有返回值的路径(当dir
既不是北也不是南时),对此表示抱歉,我们尝试简化代码。用字节码测量。但是……我认为开销是时间,而不是空间?:-)你是如何将字节码大小与第一次/第二次运行联系起来的?你能解释一下你是如何测量字节码大小的吗