4

在 Android 中,由于性能问题,建议不要使用枚举。直到最近才如此,在 Google IO 2018 中宣布枚举现在可以安全使用,尽管对于性能更高的应用程序仍然建议避免使用它们。

我的问题是:

我们可以在 android 中广泛使用 kotlin 密封类吗?

似乎密封类是枚举的扩展。如果是这样,我们应该使用类似于枚举的密封类吗?

提前致谢。

4

3 回答 3

4

密封类的性能影响与任何其他类相同。如果您创建扩展密封类的类的实例,它将是一个新实例,因此需要对它进行垃圾收集。如果你有一个object扩展的密封类,它将是一个单例并且不需要被收集(就像一个枚举常量)..

于 2018-12-03T10:37:39.853 回答
4

远离enumAndroid 的建议被夸大了。避免枚举对 Android API 来说是有意义的:它们大量使用特殊常量,应用程序中有很多这样的对象,而且它们对性能至关重要。

您的自定义应用程序代码可能只想使用几个枚举来表达业务逻辑中的实体。创建十几个甚至几百个enum实例将留下难以察觉的足迹。

同样的建议也适用于密封类:一定要使用它们并提高代码的质量。仅当您计划着手构建具有成千上万个类似枚举的常量和类的 100 KLOC 应用程序时,才停止考虑您的选择。

于 2018-12-03T10:58:20.847 回答
4

枚举

垃圾收集

在幕后,枚举是类的静态成员,因此它们不会被垃圾收集。它们会在您的应用程序的整个生命周期中保留在内存中。这可能是有利的,也可能是不利的。

垃圾收集过程在 CPU 使用方面是昂贵的。对象创建也是如此,您不想一次又一次地创建相同的对象。因此,使用枚举,您可以节省垃圾收集和对象创建的成本。这是好处。

缺点是枚举即使在不使用时也会保留在内存中,这样可以一直占用内存。

需要考虑的因素

如果您的应用中有 100 到 200 个枚举,则无需担心所有这些。但是当你有更多的时候,你可以决定是否应该使用枚举,这取决于枚举的数量、它们是否会一直使用以及分配给你的 JVM 的内存量等事实。

比较

枚举值的比较在when表达式中更快,因为它在引擎盖下tableswitch用于比较对象。

安卓

在 Android 中,启用优化后,Proguard 会将没有函数和属性的枚举转换为整数。这样,您就可以在编译时获得枚举的类型安全性,并在运行时获得整数的性能!


密封类

垃圾收集

密封类只是普通类,唯一的例外是它们需要在同一个包和同一个编译单元中扩展。所以,他们的表现相当于普通班。

密封类的子类型的对象像常规类的对象一样被垃圾收集。因此,您必须承担垃圾收集和对象创建的成本。

需要考虑的因素

当您有低内存限制时,如果您需要数千个对象,您可以考虑使用密封类而不是枚举。因为垃圾收集器可以在内存不足且对象未使用时收集对象。

如果您使用object声明来扩展密封类,则对象充当单例并且它们不会被垃圾收集,这种行为类似于枚举。但是加载关联的类并将它们保存在内存中会产生额外的成本,因为object声明具有与引擎盖下的对象同名的关联类。

比较

表达式中密封类类型的比较较慢,when因为它在引擎盖下instanceof用于比较类型。在这种情况下,枚举和密封类之间的速度差异很小。仅当您在循环中比较数千个常量时才重要。

安卓

Proguard 没有任何整数优化,如密封类的枚举。因此,如果您只想在 Android 中使用没有函数和属性的常量,那么坚持使用枚举是一个更好的主意。


而已!希望有帮助。

于 2020-12-09T15:18:02.863 回答