枚举 vs Android @Intdef - 哪一个更好优化?

18

我知道当比较常量和枚举时,常量占用的空间更少,可以是原始类型。我正在研究安卓中的@Intdef注释,有人能告诉我使用@Intdef是否比枚举更好?现在在安卓中推荐放弃使用枚举,尽可能使用@intdef移动前进吗? @Intdef可以进行多态性操作吗?

从安卓文档中关于内存 开销 的说法:

枚举常常需要比静态常量多两倍以上的内存。你应该严格避免在Android上使用枚举。

2个回答

29

@Intdef 明显更有效率,它在仅有静态final int的基础上没有负担,全部都是编译时指令。枚举是类,并且如同您链接中提到的那样会占用内存。@Intdef 获得了枚举最基本的功能,即值的验证,但没有枚举的其他特性,比如自动字符串转换。

许多 Android 文档已经过时,这很可能是其中之一。在 Android 的早期阶段,每一个位都很重要,但现在设备更加强大了。就个人而言,我会根据设计需求在这两个选项中进行选择,而不会太注重效率。此外,某些更高级注释的语法并不适合编写干净易读的代码,所以不是我的菜。然而,如果情况需要使用老式的静态整数,则 @Intdef 将为您提供保护,代价是视觉上的混乱。


5
请查看Proguard优化class/unboxing/enum。http://proguard.sourceforge.net/manual/optimizations.html - Tammen

18
除了之前的回答,我想补充一点,如果您正在使用Proguard(而且您肯定应该这样做以减小大小并混淆代码),则您的 Enums 将在可能的情况下自动转换为@IntDef

https://www.guardsquare.com/manual/configuration/optimizations

class / unboxing / enum

尽可能将枚举类型简化为整数常量。

因此,如果您有一些离散值,并且某个方法只能接受这些值而不能接受同一类型的其他值,则我会使用枚举,因为Proguard将为我优化代码。

这里是关于使用枚举的很好的帖子,由Jake Wharton编写,请查看一下。

作为库开发人员,我认识到应该完成这些小的优化,因为我们希望对使用的应用程序的大小,内存和性能影响越小越好。但是重要的是要意识到:与索引循环相比放弃Iterator分配,使用HashMap而不是像SparseArray这样的二进制搜索集合,并在适当的情况下将枚举放在您的公共API中,而不是整数值是非常好的。知道区别以做出明智的决策才是重要的,并且视频几乎完美地解释了除了此愚蠢的stat之外的所有内容。


当然,“尽可能”并不意味着太多。 - Alexey Romanov
如果我没记错的话,它会转换所有“简单”的枚举。如果枚举中有字段或方法,就不会被转换。我找不到带有这个描述的链接,但这听起来是合理的。 - Gaket
我检查了一下,如果R8对“枚举”执行相同的操作,它似乎会将它们保留为枚举类型。你试过吗? - soshial
如果枚举类型被存储在任何集合中,或者传递给接受Object类型参数的方法(例如许多日志记录方法),那么它就无法进行优化。从我所看到的情况来看,这种情况经常发生 :( - Mooing Duck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接