2017-01-23 5 views
5

Calling removeLast ist extrem langsam (es dauert einige Minuten, um 77k Elemente abzufischen). Die documentation sagt O (1) und ich würde denken, dass die Implementierung einfach die Array-Größe dekrementieren würde. Offenbar nicht:swift array removeLast extrem langsam

stack trace indicating <code>removeLast</code> calling memmove

Warum ruft remove(at: Int)?

Dieser repro Fall ist langsamer als ich erwarten würde (ich verwende, um C++ 's std::vector Leistung), aber immer noch nicht so langsam wie das, was ich in meinem Code bin zu sehen:

var array = [ Int ]() 

for i in 0..<262144 { 
    array.append(i) 
} 

print ("done appending") // we get here immediately 

let n = array.count 
for _ in 0..<n { 
    array.removeLast() // popLast is also slow 
} 

print ("done") 

Dieser Vorgang dauert 16 Sekunden auf meiner Maschine. Ein äquivalentes C++ - Programm dauert 0,002 Sekunden.

+2

Können Sie nach Code, wie Sie diese getestet? – Fogmeister

+0

Arrays sind Werttypen, die beim Schreiben kopiert werden. Es macht also Sinn, dass es eine neue Kopie auf 'removeLast' erstellt. Man sollte jedoch denken, dass dies auch schnell sein sollte. –

+0

@Fogmeister Ich versuche, Code für eine Repro zu ziehen, ohne nur meinen gesamten Code zu verlieren. Wenn ich einen ähnlichen Testfall schreibe, ist es schnell. Etwas Feines passiert. – Taylor

Antwort

4

Das Problem ist die Art, wie Sie testen. Nein Geschwindigkeitstest in einem Debug Build ist im geringsten sinnvoll. Deshalb sollten Sie immer Profil in Instrumente. Es verwendet einen Release-Build. Für realistische Ergebnisse, Profil in Instrumente auf einem Gerät. Alles andere ist eine Illusion.

Also ein Release-Build, kein Debug-Build. Sie werden sehen, dass Sie in Wirklichkeit beide print Anweisungen sofort erhalten. Anzeige von Sekunden seit dem Referenzdatum

Ergebnisse (das Telefon aus der Tasche nehmen auf meinem Computer, kein Gerät, weil ich zu faul war):

starting 506917910.056674 
done appending 506917910.060245 
done 506917910.069827 
+0

Kann bestätigen: 'swift -O test.swift' sofort abgeschlossen – Alexander

+0

Silly me. Ich bin an brauchbare Debug-Builds gewöhnt! – Taylor

+0

Das gleiche gilt für die Speicherverwaltung. Die schnelle Speicherverwaltung in einem Debug-Build im Simulator ist eine große Lüge. – matt