4

我有一本 java 游戏书建议尽可能将所有数据实现为 Int,该类型运行速度最快。它说 Byte、Char 和 Boolean 无论如何都是作为 Int 实现的,因此您不会节省空间,并且由于 Byte 数据而最终不得不在代码中进行的转换会减慢它的速度。例如,需要一个演员表

a = (字节)(b+c);

因为加法结果是一个 Int,即使 a、b 和 c 都声明为字节。

我目前有一个巨大的 2D 数组声明为我的游戏的字节,以节省空间和按位运算。真的是节省空间吗?我还在示例中看到了对 Ints 进行的按位运算,按位运算在 Ints 上是否按预期工作?

4

4 回答 4

6

这通常是不正确的。事实上,JVM 规范 §2.3对此进行了概述:

Java 虚拟机支持的原始数据类型是数字类型、boolean类型(§2.3.4)和returnAddress类型(§2.3.3)。

数字类型由整数类型(§2.3.1)和浮点类型(§2.3.2 )组成。

整数类型有:

  • byte,其值为 8 位有符号二进制补码整数,默认值为 0

  • short,其值为 16 位有符号二进制补码整数,默认值为 0

  • int,其值为 32 位有符号二进制补码整数,默认值为 0

  • long,其值为 64 位有符号二进制补码整数,默认值为 0

  • char,其值为 16 位无符号整数,表示基本多语言平面中的 Unicode 代码点,使用 UTF-16 编码,其默认值为空代码点 ( '\u0000')

现在,boolean这是一个稍微不同的故事。从§2.3.4 开始

尽管 Java 虚拟机定义了一个boolean类型,但它只提供了非常有限的支持。没有专门用于对boolean值进行操作的 Java 虚拟机指令。相反,Java 编程语言中对布尔值进行操作的表达式被编译为使用 Java 虚拟机int数据类型的值。

您可以看到字节码的差异,具体取决于您使用的是 abyte[]还是 an int[],因此它们并不相同:

byte[] b = {42};
ICONST_1
纽瓦雷 T_BYTE
DUP
ICONST_0
比普什 42
巴斯托
阿斯托尔 1

对比

int[] b = {42};
ICONST_1
纽瓦雷 T_INT
DUP
ICONST_0
比普什 42
商城
阿斯托尔 1

真的是节省空间吗?

是的,很可能是这样,尤其是在数组非常大的情况下。

按位运算在 Ints 上是否按预期工作?

是的,他们有。

于 2013-09-29T13:58:03.743 回答
1

确实byte + byte = int,需要强制转换,但是bytes 是用内存中的 8 位数据实现的,而ints 是 32 位的。因此,使用bytes 会将数组占用的内存量减少 4 倍。

例如,如果您有一个 10 x 10 的bytes 数组,其大小将为 800,但ints 的 10 x 10 数组的大小将为 3200。

有关此的更多信息

于 2013-09-29T13:56:57.403 回答
1

答案取决于您使用的是单个类型变量byte还是字节数组,byte[]. 字节数组确实节省了空间,每个 Java 字节只使用一个字节的内存(加上数组对象的恒定数量的内务数据)。但是,一个类型的局部变量byte实际上是作为 an 存储int在堆栈上的,并占用相应的 4 个字节的内存。这甚至用字节码表示——有操作码baload——“从数组中加载字节或布尔值”,但没有像iload整数那样从局部变量加载字节的操作码。类似地,局部变量charboolean变量实际上作为 int 存储在堆栈中,并且int基于 - 的操作码用于访问它们。

JLS 中的条目2.6.1还说所有局部变量在堆栈上占用一个或两个“槽”,因此单槽类型 byte、char、float 和 int 都占用相同的空间。JVM 无法寻址小于单个此类槽的单元,因此在一个字节的情况下,可以说浪费了 3 个字节。

总结一下:确实使用byte 数组来节省空间,但是在单个变量的情况下,使用 abyte而不是int不会节省空间,甚至可能会对性能产生很小的负面影响(但是,如果您需要byte语义,则可能需要它,例如反包装行为等)。

于 2013-09-29T14:33:35.197 回答
0

是的,当您执行字节加法时,返回值始终是一个整数,原因是 8 位 + 8 位加法总是会导致一个大于 8 位的值。

例如

十进制 | 二进制

255 |   1111 1111
121 |   0111 1001

376 | 1 0111 1000

所以如果你再次尝试将它存储在一个字节中,肯定会导致数据丢失。如果完成对字节的类型转换,您将得到“120”而不是 376。

您绝对可以使用 int 代替 byte,并且位操作也可以在 int 上完美运行。参考:http ://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm

于 2013-09-29T14:14:39.207 回答