Я установил флаг компилятора Swift -warn-long-function-bodies
в 90 миллисекунд, чтобы увидеть, какие функции в моем проекте слишком долго компилируются (из-за проверки типа).
У меня есть следующий метод:
func someKey(_ sectionType: SectionType, row: Int) -> String {
let suffix = row == 0 ? "top" : "content"
return "\(sectionType)_\(suffix)"
}
(SectionType
- это перечисляемое по строкам перечисление)
Как он выше, он занимает 96 мс на MacBook Pro 2017. Первое, что я пробовал, - обходить интерполяцию строк и использовать \(sectionType.rawValue)
вместо \(sectionType)
, но теперь она дает мне 106 мс. Неверный ход...
Затем я изменил:
let suffix = row == 0 ? "top" : "content"
в
let suffix = "top"
Предупреждение исчезает, поэтому троянский оператор вызывает проблемы.
Я попробовал это вместо:
let suffix: String = { // Note the type annotation!
if row == 0 {
return "top"
}
return "content"
}()
... но теперь это замыкание, которое занимает 97 мс (вся функция, 101).
Я даже попытался сделать более явным:
let suffix: String = {
if row == 0 {
return String("top")
} else {
return String("content")
}
}()
... и я получаю замыкание: 94ms; функция: 98 мс.
Что происходит?
Мой лимит на 90 миллисекунд слишком мал? Я знаю, что была (есть?) Ошибка проверки типов с словарем, но это кажется совсем другим...?
Моя среда - это Xcode 8.3.2 (8E2002),
Swift: Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
Но подождите! Там больше...
Я пробовал это тело функции:
func someKey(_ sectionType: SectionType, row: Int) -> String {
if row == 0 {
return "\(sectionType.rawValue)_top"
} else {
return "\(sectionType.rawValue)_content"
}
}
... и требуется 97 мс ~ 112 мс!?
Добавление: Я пересадил функцию и перечисление в чистый, минимальный проект (приложение с одним представлением) установил одно и то же предупреждение, но этого не происходит. Я уверен, что проект в целом влияет на этот метод каким-то образом, но пока не может понять, как еще...
Добавление 2: я тестировал статическую версию моей функции: используйте фиксированный суффикс "верх" независимо от значения row
(это занимает менее 90 мс и не вызывает никаких предупреждений), , но добавил следующий блок if
:
func someKey(_ sectionType: SectionType, row: Int) -> String {
if row == 0 {
print("zero")
} else {
print("non-zero")
}
let suffix: String = "top"
return "\(sectionType)_\(suffix)"
}
Это возвращает меня к 96 ~ 98 мс! Итак, проблема возникает при сравнении строки с нолем?
Обходной путь: Я продолжал играть с моим кодом и каким-то образом обнаружил, что если я заменил блок if
выражением switch
, проблема исчезнет:
func someKey(_ sectionType: SectionType, row: Int) -> String {
let suffix: String = {
switch row {
case 0:
return "top"
default:
return "content"
}
}()
return "\(sectionType)_\(suffix)"
}
(я не буду отвечать на свой вопрос, потому что я не считаю это объяснением того, что происходит на самом деле)