swift 中.count 方法时间复杂度到底是多少
swift中有时能看到用 xxx.count == 0 这种方式,判断一个字符串/字典/数组是否为空,也能用 xxx.isEmpty 属性是否为空,网上有人认为要用isEmpty而不是count来判断,因为后者需要遍历;
有博客 www.jianshu.com/p/77f8d6563… 认为 ”字符串是字符的集合,也遵循了RandomAccessCollection 协议“,则两者时间复杂度都为1,都可以用。
从苹果官方文档来看,各个数据结构如下
字符串 String ,不支持 RandomAccessCollection
swift库中String类对于.count方法的注释如下所示
/// The number of elements in the collection.
///
/// To check whether a collection is empty, use its `isEmpty` property
/// instead of comparing `count` to zero. Unless the collection guarantees
/// random-access performance, calculating `count` can be an O(*n*)
/// operation.
///
/// - Complexity: O(1) if the collection conforms to
/// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the length
/// of the collection.
@inlinable public var count: Int { get }
意思是当collection类型的数据结构检查是否为空时,除非collection能够保证随机访问(实现RandomAccessCollection协议),否则count计算个数都需要 O(n) 的时间复杂度,此时应该使用isEmpty方法来判断。
附上swift中是否实现了随机访问协议的数据结构如下所示,数据均来自于苹果官方关于swift的文档
AnyColumnAnyColumnSliceAnyRandomAccessCollectionArchiveHeaderArchiveHeader.EntryXATBlobArchiveHeader.FieldKeySetArrayArraySliceCMFormatDescription.ParameterSetCollectionCollectionOfOneColumnColumnSliceContiguousArrayDataDataFrame.RowDispatchDataEmptyCollectionApplicationMusicPlayer.Queue.EntriesFetchedResultsIndexPathInt.WordsInt16.WordsInt32.WordsInt64.WordsInt8.WordsKeyValuePairsMIDIEventPacket.WordCollectionMIDIPacket.ByteCollectionMLDataTable.ColumnNamesMLDataTable.Row.ValuesMLDataTable.RowsMLDataValue.SequenceTypeManagedAudioChannelLayout.ChannelDescriptionsMusicItemCollectionPKStrokePathRepeatedRowGroupingSectionedFetchResultsSectionedFetchResults.SectionUInt.WordsUInt16.WordsUInt32.WordsUInt64.WordsUInt8.WordsUnicode.Scalar.UTF16ViewUnicode.Scalar.UTF8ViewUnsafeBufferPointerUnsafeMutableAudioBufferListPointerUnsafeMutableBufferPointerUnsafeMutableMIDIEventPacketPointerUnsafeMutableMIDIPacketPointer值得注意的是Dictionary结构不在上述列表中,但是它也是支持随机访问的,其count注释如下
/// The number of keys in the dictionary.
///
/// - Complexity: O(1).
@inlinable public var count: Int { get }
总结
对于日常使用来说,常见的随机访问数据结构,Array、Dictionary、Data等能够支持随机访问的结构体,.count 的时间复杂度是O(1),你可以使用.count==0 或者 .isEmpty来判断其是否为空,性能不会有明显区别。至于String或者其他的只能顺序访问的collectton, 还是老老实实用 .isEmpty 来判空吧