swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.53k stars 10.35k forks source link

[SR-9608] marking function as mutating delivers a speedup #52054

Open swift-ci opened 5 years ago

swift-ci commented 5 years ago
Previous ID SR-9608
Radar None
Original Reporter davidbaraff (JIRA User)
Type Improvement
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Improvement, Performance | |Assignee | None | |Priority | Medium | md5: 8aedc273abb245bdbe0dd29efebd0a34

Issue Description:

In the code below, the mutating function call is faster by almost 2x than the non-mutating version. To see this, just call both functions about 25 million times. If you'd like an Xcode project which packages all this up as library and executable which runs the timing, please do " git clone git@github.com:davidbaraff/ptrTest2.git".

public struct RT {
    public init() {
        data = CxxData(x: 0, y: 0,
                       m: (0, 0, 0, 0,
                           0, 0, 0, 0,
                           0, 0, 0, 0,
                           0, 0, 0, 0))
    }

    public func call_that_copies() -> Double {
        var data_copy = data
        return analyze(&data_copy)
    }

    // exactly the same as above, just that "mutating" was added:
    public mutating func mutating_call_that_copies() -> Double {
        var data_copy = data
        return analyze(&data_copy)
    }
    var data: CxxData
}

The structure CxxData is a struct defined in C (i.e. in a bridging header file), as follows:

typedef struct CxxData {
    double x, y;
    double m[16];
 } CxxData;

while the function "analyze()" is written in C, and returns a constant value:

 double analyze(CxxData const* data) {
     return 37.0;
 }
belkadan commented 5 years ago

cc @eeckstein. Maybe we're not eliminating the copy in the non-mutating case? Although that's only safe if we really do believe the const in the C function declaration…but I think we do elsewhere.

swift-ci commented 5 years ago

Comment by David Baraff (JIRA)

My assembly-fu is weak, but when I last looked, my impression was that one path used memcpy, the other did the same copy inline (copying each variable as a separate line) and one path happened to be faster than the other.

Don't hold me to the above, though, I could easily have misread what I was reading. Assembly is not my thing...