在Android环境下,密封类对性能有什么影响?

在Android环境下,密封类对性能有什么影响?,android,performance,kotlin,enums,sealed-class,Android,Performance,Kotlin,Enums,Sealed Class,在Android中,由于性能问题,建议不要使用enum。直到最近,Google IO 2018才宣布Enum现在可以安全使用,尽管对于性能更高的应用程序,避免使用Enum仍然是可取的 我的问题是: 我们可以在android中广泛使用kotlin密封类吗 似乎密封类是枚举的扩展。如果是这样,我们应该使用类似于枚举的密封类吗 提前感谢。密封类的性能影响与任何其他类相同。如果您创建一个扩展密封类的类的实例,它将是一个新实例,因此需要对其进行垃圾收集。如果您有一个扩展密封类的对象,它将是一个单例,不需要

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

我的问题是:

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

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


提前感谢。

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

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

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

同样的建议也适用于密封类:务必使用它们并提高代码质量。只有当您计划开始构建一个包含成千上万个类似枚举的常量和类的100 KLOC应用程序时,才可以停下来考虑您的选择。

Enums 垃圾收集

实际上,枚举是类的静态成员,因此它们不会被垃圾收集。它们会在应用程序的整个生命周期内一直保留在内存中。这可能是好的,也可能是坏的

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

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

需要考虑的因素

如果你的应用程序中有100到200个枚举,那么你不必担心所有这些。但是,当您拥有更多的资源时,您就可以决定是否使用枚举,这取决于事实,例如枚举的数量、它们是否一直在使用以及分配给JVM的内存量

比较

when
表达式中比较枚举值更快,因为在引擎盖下它使用
表开关来比较对象

Android

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


密封类 垃圾收集

密封类只是普通类,唯一的例外是它们需要在同一个包和同一个编译单元中进行扩展。因此,它们的性能相当于普通类

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

需要考虑的因素

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

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

比较

表达式时,密封类类型的比较在
中较慢,因为在引擎盖下它使用
instanceof
来比较类型。在本例中,枚举和密封类之间的速度差异非常小。只有在比较循环中的数千个常量时,它才起作用

Android

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


就这样!希望有帮助