关于ZAKER 融媒体解决方案 合作 加入

成员订单是否会像在 C 或 C 中那样在 Java 中产生性能差异?

CocoaChina 11-17

在 C 和 C 中 , 不允许编译器重新排序结构的数据成员 , 因此如果您不小心订购它们 , 最终会浪费空间 . 例如:

struct S { int i; void *p; int i2;};

在具有 32 位整数和 64 位指针的平台上 , 我将首先放置 , 然后是 32 位填充 , 以便 p 可以进行 64 位对齐 . 然后 i2 占用下一个字的一半 , 接着是另外 32 位的填充 . 结果结构长度为 24 个字节 , 而如果首先声明 p, 则它只有 16 个字节长 . 如果阵列中有很多这些结构 , 找到并删除填充有时可能是一个重要的优化 , 以节省内存并减少缓存流失 .

我很想知道 Java 是否具有相同的功能 . 未装箱的类型 ( 例如 int 和 boolean ) 是否与引用相同或更小?如果它们更小 , 是否允许编译器重新排序它们以避免插入填充以对齐后续字段?最后 , 如果是 , 那么任何编译器都这样做吗?

我现在对此没有特别的优化需求 , 我只是想知道在选择声明我的字段的顺序时是否应该记住这一点 , 就像我在 C 中所做的那样 .

最佳答案

int 类型总是 32 位 , 即使在 64 位 JVM 中 , 引用通常也是 32 位 .

在不利方面 ,Java 在每个对象的开头有一个 8-12 字节的标头 , 并使用 8 字节对齐 . BTW 某些 C 环境具有 16 字节对齐 .

Are unboxed types ( such as int and boolean ) the same size as references or smaller?

对于 boolean,byte,char 和 short, 你可以期望它们更小 , 但是对于 long 和 double, 基元可以比引用更大 .

And if they ’ re smaller, is the compiler allowed to reorder them to avoid inserting padding to align subsequent fields?

JIT 可以重新组织字段甚至优化它们 .

Finally, if it is, do any compilers do this?

javac 编译接下来没有优化 , 查看字节代码将为您提供关于运行时会发生什么的一些线索 . 无论如何 ,JIT 都可以优化对象中的字段 .

I ’ m just curious to know if I should bear this in mind when choosing what order to declare my fields, like I do in C.

恕我直言 , 您可以假设您在 C 中使用的几乎所有优化技巧都不再适用于 Java. 在为数不多的人中 , 他们可能并不完全相同 .

您应该假设 JIT 将根据需要优化代码 , 并使用分析器来确定是否以及何时出现问题 . 然后才考虑出于性能原因而改变代码 .

以上内容由"CocoaChina"上传发布 查看原文

觉得文章不错,微信扫描分享好友

扫码分享

热门推荐

查看更多内容