在Swift中调用Array上的.count分配count变量

Set*_*hmr 5 arrays enumeration count compiler-optimization swift

我偶尔来到一个我不会改变数组内容的地方,但我需要在函数上多次知道它的计数.将数组的.count分配给变量并多次使用它是否更有效,或者编译器是否使效率等效?

dfr*_*fri 5

我们来调查一下吧!相当于myArray.count访问存储的属性,或者它是计算属性,如果对非变异数组重复调用,则会执行一些“不必要的”计算?(忽略编译器的聪明才智)

/// The number of elements in the array.
public var count: Int {
  return _getCount()
}

// ... what is function _getCount()?

internal func _getCount() -> Int {
  return _buffer.count
}

// ... what is property _buffer?
internal var _buffer: _Buffer

// ... what is type _Buffer? (Swift)
internal typealias _Buffer = _ContiguousArrayBuffer<Element>

// ... what is type _ContiguousArrayBuffer?
// --> switch source file
Run Code Online (Sandbox Code Playgroud)
import SwiftShims

/// Class used whose sole instance is used as storage for empty
/// arrays.  The instance is defined in the runtime and statically
/// initialized.  See stdlib/runtime/GlobalObjects.cpp for details.
internal struct _ContiguousArrayBuffer<Element> : _ArrayBufferProtocol {

  // ... conformance to _ArrayBufferProtocol

  /// The number of elements the buffer stores.
  internal var count: Int {
    get {
      return __bufferPointer.header.count
    }
    // ...
  }   
  // ...
}

// ... what is property __bufferPointer?
var __bufferPointer: ManagedBufferPointer<_ArrayBody, Element>

// what is type _ArrayBody?
// we notice for now that it is used in the following class:
internal final class _EmptyArrayStorage
  : _ContiguousArrayStorageBase {
  // ...

  var countAndCapacity: _ArrayBody // telling name for a tuple? :)
}

// --> proceed to core/ArrayBody.swift
Run Code Online (Sandbox Code Playgroud)
import SwiftShims

// ...

internal struct _ArrayBody {
  var _storage: _SwiftArrayBodyStorage

  // ...

  /// The number of elements stored in this Array.
  var count: Int {
    get {
      return _assumeNonNegative(_storage.count)
    }
    set(newCount) {
      _storage.count = newCount
    }
  } 
}

// we are near our price! we need to look closer at  _SwiftArrayBodyStorage, 
// the type of _storage, so lets look at SwiftShims, GlobalObjects.cpp
// (as mentioned in source comments above), specifically
// --> switch source file
Run Code Online (Sandbox Code Playgroud)
struct _SwiftArrayBodyStorage {
  __swift_intptr_t count;              
  __swift_uintptr_t _capacityAndFlags;
};

// Yay, we found a stored property!
Run Code Online (Sandbox Code Playgroud)

因此最终count是一个存储的属性,并且不会在每次调用时计算,因此没有理由arr.count自己显式存储该属性。