Tina Liu 94adc6a958
Improve performance for calling Locale.identifier from NS/CFLocale (#1051)
- use @_effects(releasenone) to solemnly swear to the compiler that we won't release anything inside these getters, eliminating refcounting to call them

- micro-optimize identifierDoesNotRequireSpecialCaseHandling, allowing us to delete the cache of it without regressing perf

On the test app this goes from "so slow I didn't bother to see how long it takes to finish" to "finishes in around 1 second"

Resolves 137885111

Co-authored-by: David (Swift) Smith <david_smith@apple.com>
2024-11-18 10:22:46 -08:00

271 lines
5.8 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
/// An "unlocalized" Locale, for use in apps that do not otherwise care about localization. No matter which identifier or settings you initialize it with, it will still be `en_001`.
internal final class _LocaleUnlocalized : _LocaleProtocol, @unchecked Sendable {
let _prefs: LocalePreferences?
required init(identifier: String, prefs: LocalePreferences? = nil) {
_prefs = prefs
}
required init(name: String?, prefs: LocalePreferences, disableBundleMatching: Bool) {
_prefs = prefs
}
required init(components: Locale.Components) {
_prefs = nil
}
func copy(newCalendarIdentifier identifier: Calendar.Identifier) -> any _LocaleProtocol {
// Nothing changes here
self
}
var debugDescription: String {
"unlocalized en_001"
}
var identifier: String {
"en_001"
}
func identifierDisplayName(for value: String) -> String? {
nil
}
func languageCodeDisplayName(for value: String) -> String? {
nil
}
func countryCodeDisplayName(for regionCode: String) -> String? {
nil
}
func scriptCodeDisplayName(for scriptCode: String) -> String? {
nil
}
func variantCodeDisplayName(for variantCode: String) -> String? {
nil
}
func calendarIdentifierDisplayName(for value: Calendar.Identifier) -> String? {
nil
}
func currencyCodeDisplayName(for value: String) -> String? {
nil
}
func currencySymbolDisplayName(for value: String) -> String? {
nil
}
func collationIdentifierDisplayName(for value: String) -> String? {
nil
}
func collatorIdentifierDisplayName(for collatorIdentifier: String) -> String? {
nil
}
var languageCode: String? {
"en"
}
var scriptCode: String? {
nil
}
var variantCode: String? {
nil
}
var regionCode: String? {
"001"
}
#if FOUNDATION_FRAMEWORK
var exemplarCharacterSet: CharacterSet? {
LocaleCache.cache.fixed(identifier).exemplarCharacterSet
}
#endif
var calendar: Calendar {
Calendar.current
}
var calendarIdentifier: Calendar.Identifier {
.gregorian
}
var collationIdentifier: String? {
"standard"
}
var usesMetricSystem: Bool {
true
}
var decimalSeparator: String? {
"."
}
var groupingSeparator: String? {
","
}
var currencySymbol: String? {
"¤"
}
var currencyCode: String? {
nil
}
var collatorIdentifier: String? {
identifier
}
var quotationBeginDelimiter: String? {
""
}
var quotationEndDelimiter: String? {
""
}
var alternateQuotationBeginDelimiter: String? {
""
}
var alternateQuotationEndDelimiter: String? {
""
}
var measurementSystem: Locale.MeasurementSystem {
.metric
}
var currency: Locale.Currency? {
nil
}
var numberingSystem: Locale.NumberingSystem {
.latn
}
var availableNumberingSystems: [Locale.NumberingSystem] {
[.latn]
}
var firstDayOfWeek: Locale.Weekday {
.monday
}
var weekendRange: WeekendRange? {
// Weekend range for 001 region
WeekendRange(onsetTime: 0, ceaseTime: 86400, start: 7, end: 1)
}
var minimumDaysInFirstWeek: Int {
// Minimum days in first week for 001 region
1
}
var language: Locale.Language {
Locale.Language(components: .init(languageCode: .init("en"), script: nil, region: .init("001")))
}
func identifier(_ type: Locale.IdentifierType) -> String {
switch type {
case .bcp47: "en-001"
case .cldr: "en_001"
case .icu: "en_001"
}
}
var hourCycle: Locale.HourCycle {
.zeroToTwentyThree
}
var collation: Locale.Collation {
.standard
}
var region: Locale.Region? {
Locale.Region("001")
}
var timeZone: TimeZone? {
nil
}
var subdivision: Locale.Subdivision? {
nil
}
var variant: Locale.Variant? {
nil
}
var temperatureUnit: LocalePreferences.TemperatureUnit {
.celsius
}
var forceHourCycle: Locale.HourCycle? {
nil
}
func forceFirstWeekday(_ calendar: Calendar.Identifier) -> Locale.Weekday? {
nil
}
func forceMinDaysInFirstWeek(_ calendar: Calendar.Identifier) -> Int? {
nil
}
var forceMeasurementSystem: Locale.MeasurementSystem? {
nil
}
var forceTemperatureUnit: LocalePreferences.TemperatureUnit? {
nil
}
#if FOUNDATION_FRAMEWORK && !NO_FORMATTERS
func customDateFormat(_ style: Date.FormatStyle.DateStyle) -> String? {
nil
}
#endif
var prefs: LocalePreferences? {
_prefs
}
var identifierCapturingPreferences: String {
identifier
}
#if FOUNDATION_FRAMEWORK
func pref(for key: String) -> Any? {
nil
}
func bridgeToNSLocale() -> NSLocale {
Locale(identifier: identifier) as NSLocale
}
#endif
}