Why Choose Struct Over Class?

前端 未结 16 2275

Playing around with Swift, coming from a Java background, why would you want to choose a Struct instead of a Class? Seems like they are the same thing, with a Struct offeri

16条回答
  •  迷失自我
    2020-11-22 06:00

    Since struct instances are allocated on stack, and class instances are allocated on heap, structs can sometimes be drastically faster.

    However, you should always measure it yourself and decide based on your unique use case.

    Consider the following example, which demonstrates 2 strategies of wrapping Int data type using struct and class. I am using 10 repeated values are to better reflect real world, where you have multiple fields.

    class Int10Class {
        let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int
        init(_ val: Int) {
            self.value1 = val
            self.value2 = val
            self.value3 = val
            self.value4 = val
            self.value5 = val
            self.value6 = val
            self.value7 = val
            self.value8 = val
            self.value9 = val
            self.value10 = val
        }
    }
    
    struct Int10Struct {
        let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int
        init(_ val: Int) {
            self.value1 = val
            self.value2 = val
            self.value3 = val
            self.value4 = val
            self.value5 = val
            self.value6 = val
            self.value7 = val
            self.value8 = val
            self.value9 = val
            self.value10 = val
        }
    }
    
    func + (x: Int10Class, y: Int10Class) -> Int10Class {
        return IntClass(x.value + y.value)
    }
    
    func + (x: Int10Struct, y: Int10Struct) -> Int10Struct {
        return IntStruct(x.value + y.value)
    }
    

    Performance is measured using

    // Measure Int10Class
    measure("class (10 fields)") {
        var x = Int10Class(0)
        for _ in 1...10000000 {
            x = x + Int10Class(1)
        }
    }
    
    // Measure Int10Struct
    measure("struct (10 fields)") {
        var y = Int10Struct(0)
        for _ in 1...10000000 {
            y = y + Int10Struct(1)
        }
    }
    
    func measure(name: String, @noescape block: () -> ()) {
        let t0 = CACurrentMediaTime()
    
        block()
    
        let dt = CACurrentMediaTime() - t0
        print("\(name) -> \(dt)")
    }
    

    Code can be found at https://github.com/knguyen2708/StructVsClassPerformance

    UPDATE (27 Mar 2018):

    As of Swift 4.0, Xcode 9.2, running Release build on iPhone 6S, iOS 11.2.6, Swift Compiler setting is -O -whole-module-optimization:

    • class version took 2.06 seconds
    • struct version took 4.17e-08 seconds (50,000,000 times faster)

    (I no longer average multiple runs, as variances are very small, under 5%)

    Note: the difference is a lot less dramatic without whole module optimization. I'd be glad if someone can point out what the flag actually does.


    UPDATE (7 May 2016):

    As of Swift 2.2.1, Xcode 7.3, running Release build on iPhone 6S, iOS 9.3.1, averaged over 5 runs, Swift Compiler setting is -O -whole-module-optimization:

    • class version took 2.159942142s
    • struct version took 5.83E-08s (37,000,000 times faster)

    Note: as someone mentioned that in real-world scenarios, there will be likely more than 1 field in a struct, I have added tests for structs/classes with 10 fields instead of 1. Surprisingly, results don't vary much.


    ORIGINAL RESULTS (1 June 2014):

    (Ran on struct/class with 1 field, not 10)

    As of Swift 1.2, Xcode 6.3.2, running Release build on iPhone 5S, iOS 8.3, averaged over 5 runs

    • class version took 9.788332333s
    • struct version took 0.010532942s (900 times faster)

    OLD RESULTS (from unknown time)

    (Ran on struct/class with 1 field, not 10)

    With release build on my MacBook Pro:

    • The class version took 1.10082 sec
    • The struct version took 0.02324 sec (50 times faster)

提交回复
热议问题