-1

我有一个非常大的数字列表,我想将它传递给一个函数来对其进行一些操作。最初,我创建了一个带有 inout 属性的函数。众所周知,swift 中的 inout 不会通过引用传递,而是对函数进行初始复制,然后在返回时将值复制回。这听起来很昂贵。我决定将我的列表包装在一个类中并通过引用传递,以优化和减少复制时间。有趣的是,似乎 inout 函数比通过引用函数更快。我什至对 inout 变量进行了操作,以使编译器在写入时进行复制。任何想法为什么 inout 函数比通过引用传递更快?

class ReferencedContainer {
    var container = [Int:Bool]()
}

func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
    let startTime = CFAbsoluteTimeGetCurrent()
    operation()
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print("Time elapsed for \(title): \(timeElapsed) s.")
}

func inoutTest(list: inout [Int]?) -> [Int]? {
    list![0]=1
    return list
}

func refTest(list: ReferencedContainer) -> ReferencedContainer {
    list.container[0] = true
    return list
}


var list : [Int]? = [Int]()
for i in 0...10000 {
list?.append(i)
}

var ref = ReferencedContainer()
for i in list!
{
    ref.container[i] = true
}
printTimeElapsedWhenRunningCode(title: "refTest", operation: { refTest(list: ref)})

printTimeElapsedWhenRunningCode(title: "inout", operation: { inoutTest(list: &list)})

refTest 所用时间:0.0015590190887451172 秒。

输入输出经过的时间:0.00035893917083740234 秒。

4

2 回答 2

2

众所周知,swift 中的 inout 不会通过引用传递,而是对函数进行初始复制,然后在返回时将值复制回。这听起来很昂贵。

它不是。它正在复制一个[Int: Bool](aka Dictionary<Int, Bool>) 的实例,它只是一个指针。自己看,用print(MemoryLayout<[Int: Bool]>.size)

于 2019-06-25T03:53:22.787 回答
2

在许多可能的情况下,需要考虑两件事:

  1. inout 可以使用引用调用作为优化,请参阅In-Out 参数
  2. 您的两个测试完全不同,一个使用选项和一个数组,另一个使用字典。你也只测试一个突变,尝试做更多。您应该拥有的唯一区别是 struct 与 class ,如果您尝试获得相似的速度,或者其中一个比另一个更快 - 无论哪种方式。
于 2019-06-25T04:19:38.993 回答