16

String.hasPrefix (or [NSString hasPrefix]) was always part of Foundation. However, I just noticed that now we also have starts(with:).

This method comes from Sequence but it also works for String.

My question is, which one should I prefer? Are there any performance considerations? I'm used to hasPrefix from Objective-C days, but starts(with:) is more intuitive and works for other sequences.

noamtm
  • 12,435
  • 15
  • 71
  • 107

1 Answers1

25

String.hasPrefix() is implemented in StringLegacy.swift as

extension String {

  public func hasPrefix(_ prefix: String) -> Bool {
    if _fastPath(self._guts.isNFCFastUTF8 && prefix._guts.isNFCFastUTF8) {
      guard prefix._guts.count <= self._guts.count else { return false }
      return prefix._guts.withFastUTF8 { nfcPrefix in
        let prefixEnd = nfcPrefix.count
        return self._guts.withFastUTF8(range: 0..<prefixEnd) { nfcSlicedSelf in
          return _binaryCompare(nfcSlicedSelf, nfcPrefix) == 0
        }
      }
    }

    return starts(with: prefix)
  }

}

which means (if I understand it correctly): If both the string and the prefix candidate use a UTF-8 based storage then the UTF-8 bytes are compared directly. Otherwise it falls back to starts(with:) and does a Character based comparison.

So there is no difference in the result, but hasPrefix() is optimized for native Swift strings.

Note: This is the from the master (Swift 5) branch, the situation might be different in earlier versions.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Makes sense, I expected a string-specific implementation to be optimized. But the docs don't say anything about it (the doc for String's `starts(with:)` should recommend using `hasPrefix` instead). And the fact that it's implemented in String**Legacy**.swift raises eyebrows. – noamtm Feb 21 '19 at 13:26
  • Moreover, it would make even more sense if String would provide an optimized implementation of `starts(with:)`. – noamtm Feb 21 '19 at 13:28
  • @noamtm: The `String.start(with:)` *documentation* is probably auto-generated from the generic Sequence method (to which String conforms). – I understand your concerns about the file name, but I do not know the intention behind it. – Martin R Feb 21 '19 at 13:39