Swift: Mirror(reflecting: self) 太慢了?
Swift: Mirror(reflecting: self) too slow?
我正在尝试用我 class 的属性制作一本字典。
class SomeClass() {
var someString = "Hello, Whosebug"
var someInt = 42 // The answer to life, the universe and everything
var someBool = true
func objectToDict() -> [String: String] {
var dict = [String: String]()
let reflection = Mirror(reflecting: self)
for child in reflection.children {
if let key = child.label {
dict[key] = child.value as? AnyObject
}
return dict
}
}
但是objectToDict()
非常慢。有没有办法加快速度,或者可能是另一种将 属性 值添加到字典的方法?
不仅速度慢,而且也不是一个好主意:镜像仅用于调试内省。您应该自己构建字典。这确保您可以灵活地以完全正确的方式存储所有数据,并将您的 Swift 属性 名称与您生成的字典的键分离。
class SomeClass {
var someString = "Hello, Whosebug"
var someInt = 42 // The answer to life, the universe and everything
var someBool = true
func objectToDict() -> [String: AnyObject] {
return ["someString": someString, "someInt": someInt, "someBool": someBool]
}
}
我不同意大多数其他用户的观点。使用反射可以减少代码,这意味着开发、维护和测试产品的时间更少。有了像 EVReflection
这样写得很好的库,你就不用太担心幕后的事情了。
但是,如果性能将成为一个问题,请不要完全使用基于反射的方法。我想说这对我来说在前端开发中从来都不是真正的问题,尤其是在 iOS 中,但在后端开发中却不容忽视。
为了看看它有多慢,我 运行 在 Xcode 中进行了一些测试。我会写一篇关于它的博客,但一般来说,获取 Mirror
并不是最糟糕的部分(加上它可能会在内存中捕获 属性 列表),所以用 objc 运行时替换它不会'不要改变太多的情况。另一方面,setValue(_, forKey)
出奇地慢。考虑到在现实生活中还需要执行检查dynamicType
等任务,使用动态方式肯定会慢100+倍,这对于服务器开发来说是不能接受的。
- Looping 1,000,000 times for a class with 1 `Int` property
- Getting mirror: 1.52
- Looping throw mirror and set `child.value`: 3.3
- Looping throw mirror and set `42`: 3.27
- Setting value `42`: 0.05
同样,iOS 我会继续使用它来节省我的时间。希望最终客户不会关心它是 0.005 秒还是 0.0005 秒。
我正在尝试用我 class 的属性制作一本字典。
class SomeClass() {
var someString = "Hello, Whosebug"
var someInt = 42 // The answer to life, the universe and everything
var someBool = true
func objectToDict() -> [String: String] {
var dict = [String: String]()
let reflection = Mirror(reflecting: self)
for child in reflection.children {
if let key = child.label {
dict[key] = child.value as? AnyObject
}
return dict
}
}
但是objectToDict()
非常慢。有没有办法加快速度,或者可能是另一种将 属性 值添加到字典的方法?
不仅速度慢,而且也不是一个好主意:镜像仅用于调试内省。您应该自己构建字典。这确保您可以灵活地以完全正确的方式存储所有数据,并将您的 Swift 属性 名称与您生成的字典的键分离。
class SomeClass {
var someString = "Hello, Whosebug"
var someInt = 42 // The answer to life, the universe and everything
var someBool = true
func objectToDict() -> [String: AnyObject] {
return ["someString": someString, "someInt": someInt, "someBool": someBool]
}
}
我不同意大多数其他用户的观点。使用反射可以减少代码,这意味着开发、维护和测试产品的时间更少。有了像 EVReflection
这样写得很好的库,你就不用太担心幕后的事情了。
但是,如果性能将成为一个问题,请不要完全使用基于反射的方法。我想说这对我来说在前端开发中从来都不是真正的问题,尤其是在 iOS 中,但在后端开发中却不容忽视。
为了看看它有多慢,我 运行 在 Xcode 中进行了一些测试。我会写一篇关于它的博客,但一般来说,获取 Mirror
并不是最糟糕的部分(加上它可能会在内存中捕获 属性 列表),所以用 objc 运行时替换它不会'不要改变太多的情况。另一方面,setValue(_, forKey)
出奇地慢。考虑到在现实生活中还需要执行检查dynamicType
等任务,使用动态方式肯定会慢100+倍,这对于服务器开发来说是不能接受的。
- Looping 1,000,000 times for a class with 1 `Int` property
- Getting mirror: 1.52
- Looping throw mirror and set `child.value`: 3.3
- Looping throw mirror and set `42`: 3.27
- Setting value `42`: 0.05
同样,iOS 我会继续使用它来节省我的时间。希望最终客户不会关心它是 0.005 秒还是 0.0005 秒。