代码之家  ›  专栏  ›  技术社区  ›  user3352185

斯威夫特:镜子(反射:自我)太慢?

  •  3
  • user3352185  · 技术社区  · 8 年前

    我正在试着用我的一个类的属性制作一本字典。

    class SomeClass() {
        var someString = "Hello, stackoverflow"
        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() 非常慢。有没有加快速度的方法,或者可能有其他方法将属性值添加到Dictionary?

    2 回复  |  直到 8 年前
        1
  •  6
  •   superarts.org    7 年前

    我不同意大多数其他用户的意见。使用反射可以减少代码,这意味着开发、维护和测试产品的时间更少。拥有一个编写良好的库 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
    

        2
  •  2
  •   andyvn22    8 年前

    这不仅速度慢,而且不是一个好主意: 镜像仅用于调试自检 。你应该自己构造字典。这确保您可以灵活地以正确的方式存储所有数据,并且还可以将Swift属性名称与生成的字典的键分离开来。

    class SomeClass {
        var someString = "Hello, stackoverflow"
        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]
        }
    }