Swift中字符串支持的枚举的性能

我在 Swift中有很多由Strings支持的枚举.考虑到枚举所代表的内容,这是有道理的,并且考虑到以下代码块永远不必写入,这是实用的:
public enum MyEnum : String {
    ...
    func stringValue() -> String {
        switch self {
            ...
        }
    }
    // I can just use .rawValue() instead.
}

我无法找到的东西是关于非Integral类型支持的Enums的内部工作和性能的大量信息.具体来说,我正在寻找以下问题的答案:

> Enum比较仍然保证为O(1),如果是这样,那么通过String散列或Enums得到它们自己的==运算符,无论基础类型如何(“真O(1)”)都可以使用它的可能值?
>对于整数和非整数类型,Enum(rawValue :)构造函数的复杂性是多少?

看看这段代码:
enum A {
    case A1,A2
}

enum B : Int {
    case B1 = 1
    case B2
}

enum C : String {
    case C1
    case C2
}

A.A1.hashValue    // 0
A.A2.hashValue    // 1

B.B1.hashValue    // 0
B.B2.hashValue    // 1

C.C1.hashValue    // 0
C.C2.hashValue    // 1

正如您所看到的,任何枚举的hashValue等于大小写的数量,无论rawValue如何,甚至还有一个.这肯定是因为在下面,每个枚举只是一个数字,而rawValue只是一个数组,它将这些数字(索引)映射到相应的值.因此

>枚举比较总是只是两个数字之间的比较,你可以只比较hashValues – > O(1)复杂性(未经测试,但我很确定)
>我不知道如何使用原始值进行初始化,很可能是O(1)虽然(错误,它是O(n)!,请参见下面的编辑),因为所有可能的RawValue类型都是Hashable,因此可以将它们存储在Hashmap中,这意味着O(1)索引.

也就是说,枚举可以像这样实现:

enum M : RawRepresentable {
    case M1    // rawValue = 4,hashValue = 0
    case M2    // rawValue = 7,hashValue = 1

    typealias RawValue = Int

    // Int is Hashable -> Store in Dictionary -> O(1)
    static let rawToEnum : [RawValue : M] = [
        4 : .M1,7 : .M2
    ]

    // hashValue is index of this array
    static let hashToRaw : [RawValue] = [
        4,7
    ]

    var rawValue : RawValue {
        return M.hashToRaw[hashValue]
    }

    init?(rawValue: RawValue) {
        if let m = M.rawToEnum[rawValue] {
            self = m
        } else {
            self = .M1    // Failed,assign a value to let it compile
            return nil
        }
    }
}

编辑:似乎初始化枚举是O(n)(其中n是案例数)复杂性!

我做了一些性能测试,在那里我创建了4个不同的枚举,每个枚举128,256,512,1024个案例.然后我让程序选择每个枚举的128个随机rawValues,制作它们的数组并重复该数组20次(以获得更准确的时间).然后使用每个rawValues初始化枚举.以下是结果(发布版本):

Default rawValue: 20 repetitions
 128 cases -> 0.003 sec (33% StDev)
 256 cases -> 0.006 sec (14% StDev)
 512 cases -> 0.014 sec (15% StDev)
1024 cases -> 0.025 sec (10% StDev)

你可以查看我创建的测试项目here(XCode 7 beta 6)

另一个编辑:我在测试项目中添加了枚举,这与我上面展示的方式符合RawRepresentable,再次使用128,512和1024个案例完全相同的设置.结果(如预期的那样)是O(1)!所以显然创建自己的枚举更快!我只是不明白为什么Swift开发人员没有这样做…性能btw是为RawRepresentable的自定义实现重复200次(枚举初始化量是默认rawValues的10倍):

Custom rawValue: 200 repetitions
 128 cases -> 0.008 sec ( 7% StDev)
 256 cases -> 0.008 sec (15% StDev)
 512 cases -> 0.010 sec (19% StDev)
1024 cases -> 0.008 sec (26% StDev)

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...