我想让一个类的属性及其子类在运行时通过整数 id 或属性名称进行读写,其性能尽可能接近常规编译的读写。这个类可能有很多实例,它的子类(最多 100 万个),每个类可能有数百个属性,所以我想最小化每个类实例中每个属性使用的内存。
我看到的广泛的解决方案组正在使用反射,使每个属性成为可变类的实例,然后保留这些映射,或者编写巨大的 when 语句。
我已经测试了反射实现的性能(见下文)。在我的测试中,这需要 15 倍于直接访问该属性的时间。
这可以改进,还是有更好的方法来做到这一点?
class ReflectionClass {
@FieldId(1)
var intField = 0
fun getPropById(id: Int): Any? {
val property = propertiesById[id]
return property?.get(this)
}
fun setIntPropById(id: Int, value: Int) {
val property = propertiesById[id]
if (property is KMutableProperty1) {
property?.setter?.call(this, value)
}
}
fun getPropByName(name: String): Any? {
val property = propertiesByName[name]
return property?.get(this)
}
fun setIntPropByName(name: String, value: Int) {
val property = propertiesByName[name]
if (property is KMutableProperty1) {
property as KMutableProperty1<ReflectionClass, Int>
property.set(this, value)
}
}
companion object {
//private val propertiesById = HashMap<Int, KProperty1<ReflectionClass,*>>()
private val propertiesById = HashMap<Int, KProperty1<ReflectionClass, *>?>()
private val propertiesByName = HashMap<String, KProperty1<ReflectionClass, *>>()
init {
val fields = ReflectionClass::class.memberProperties.forEach { property ->
val id = property.findAnnotation<FieldId>()
if (id != null) {
propertiesById.put(id.id, property)
propertiesByName.put(property.name, property)
}
}
}
}
}