Jednym z największych zabójców wydajności jest wynik po prawej stronie placu zabaw. Teraz pokażę ci, jak zminimalizować to wyjście.
Zobacz na końcu przykładowy kod.
Najlepszy występ
najbardziej wydajnych sposobów jest, aby cały kod krytyczny wydajności w pliku w folderze na placu zabaw Sources
.swift
.
Uwaga: W celu korzystania z funkcji, klas, właściwości i metod z folderu Sources
trzeba je public
zaznaczyć. Jeśli chcesz podklasować klasę, musisz oznaczyć ją jako open
.
dobrych wyników, ale kod brzydki
Poniższy sposób (myślę, że to nie jest oficjalna/ma) może być użyty do wyłączenia wyjścia zabaw, ale także prowadzi do brzydkiego kodu. Jednak jest to dobre dla tymczasowego wyłączania wyjścia.
Istnieją dwa główne sposoby (i dwie sztuczki), aby osiągnąć minimalną ilość mocy (Jeśli okaże się lepszy sposób daj nam znać):
użycie nawiasów wokół Void
(lub Void?
) wyrażenia, takie jak przypisania (zwykle prowadzi do braku wyników, patrz także 3.).
var x = 0 // output: 0
(x = 1) // NO output
(x = 2 * x - 1) // NO output
(x.negate()) // NO output
Uwaga: W Swift zadanie powraca Void
aw przypadku optional chaining jest Void?
.
var x: (Int, Int)? = nil
if (x?.0 = 0) != nil {
// assignment was successful (x!=0 and now x=(0, x.1))
} else {
// assignment was not successful (x==nil)
}
Inicjalizuj i deklaruj zmienne oddzielnie.
var x: Int // NO output
(x = 0) // NO output
1. Jeśli nie działa dodatkową no-op (bez operacji) wiersz powyżej lub poniżej ()
.
Dzieje się zamknięć pojedynczych linii (i prawdopodobnie w innych kontekstach), na przykład: (patrz też poniższy kod)
[1, 4, 5, 6].mmap{
() // without this line the line below would yield to an output
($1 = $0 + 1)
} as [Int]
Zamiast owijania każdy wiersz w nawiasie można również użyć krotka wszystkie wyrażenia, które jest następnie przypisane do zmiennej:
var a: Any // this may be a useful definition in this context
var x: Int
var y: Int
(a = (x = 0,
y = 1,
x = y + 1,
y = x*x))
jednak może to doprowadzić do katastrofy wcięcia ...
Gdzie to nie działa (Nie znalazłem sposobu, aby usunąć wyjście; Ta lista nie jest prawdopodobnie zakończyć):
return
s w funkcji i zamknięć
- Deklaracja
Optional
zmiennych np: var x: Int?
Przykładem nowej metody map
na Sequence
Sposób użycia: Patrz wyżej w punkcie 3.
Podpis Sequence.map
jest
func map<T>(_ transform: (Self.Element) throws -> T) rethrows -> [T]
Ponieważ nie znaleźli sposób, jak usunąć wyjście return
s można użyć zamknięcie z inout
argumentu (uzyskać „Powrót” wartość z cesją) . Ewentualny podpis może następnie być:
func mmap<U>(_ transform: (Element, inout U?) ->()) -> [U]
więc możemy przejść nil
w inout
argumentu, ponieważ jest to dobry domyślny dla każdej możliwej U
bez nakładające ograniczenia na U
które mogłyby wymagać generator instancji (np init() { ... }
) .
Niestety, Swfit ma trudności z wnioskiem o U
, więc musisz pomóc kompilatorowi z adnotacjami typu jawnego. Ponadto var newElement: U?
ma powrót nil
na pasku bocznym.
Teraz użyję Any
zamiast U?
:
extension Sequence {
// ATTENTION: this is not as performant as the normal `map`!
func mmap<U>(transform: (Element, inout Any) ->()) -> [U] {
var result: [U]
(result = [U]())
for element in self {
var newElement: Any
(newElement = 0) // some placeholder element
(transform(element, &newElement))
// assume the inout element to be of type `U`
(result.append(newElement as! U))
}
return result // the ONLY output in this method
}
}
Twój przykładowy kod
Korzystanie Swift 4
var count = 0
for i in 0..<1_000_000_000 {
(count += 1)
if count % 100_000 == 0 {
// print only every 100_000th loop iteration
print(count)
}
}
Bez nawiasie: około 10,000 iteracji pętli na sekundę
Z nawiasem: około 10.000.000 powtórzeń pętli na sekundę !!!
Być może optymalizujący kompilator zredukuje ten kod do: 'var count = 1000000000'. – zaph
@Zaph Spróbuj wkleić ten kod na plac zabaw, a zobaczysz co mam na myśli. – zakhej
Dlaczego ludzie głosują za blisko? Nie wiesz, co to jest plac zabaw? – zakhej