Files
swift-mirror/stdlib/public/core/StringHashable.swift
Michael Ilseman 8851bac1be [String] Inlining, NFC fast paths, and more.
Add inlinability annotations to restore performance parity with 4.2 String.

Take advantage of known NFC as a fast-path for comparison, and
overhaul comparison dispatch.

RRC improvements and optmizations.
2018-11-04 10:42:41 -08:00

62 lines
1.9 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
extension String : Hashable {
/// Hashes the essential components of this value by feeding them into the
/// given hasher.
///
/// - Parameter hasher: The hasher to use when combining the components
/// of this instance.
@inlinable // For pre-normal fast paths
public func hash(into hasher: inout Hasher) {
// TODO(UTF8 perf): pre-normal checks, fast-paths, etc.
_guts._normalizedHash(into: &hasher)
}
}
extension StringProtocol {
/// Hashes the essential components of this value by feeding them into the
/// given hasher.
///
/// - Parameter hasher: The hasher to use when combining the components
/// of this instance.
@inlinable
public func hash(into hasher: inout Hasher) {
// TODO(UTF8 perf): skip extra copy
_ephemeralString.hash(into: &hasher)
}
}
extension _StringGuts {
@usableFromInline // @opaque
@inline(never) // slow-path
internal func _normalizedHash(into hasher: inout Hasher) {
if self.isNFC && self.isFastUTF8 {
self.withFastUTF8 {
hasher.combine(bytes: UnsafeRawBufferPointer($0))
}
} else {
// TODO(UTF8 perf): Other fast-paths, incremental (non-allocating)
// normalization, etc.
String(self)._normalize().withUnsafeBytes {
hasher.combine(bytes: $0)
}
}
hasher.combine(0xFF as UInt8) // terminator
}
}