Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swift array removeLast extremely slow

Tags:

Calling removeLast is extremely slow (it takes several minutes to pop off 77k elements). The documentation says O(1) and I would think the implementation would simply decrement the array size. Evidently not:

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

Why is it calling remove(at: Int)?

This repro case is slower than I would expect (I'm used to C++'s std::vector performance), but still not as slow as what I'm seeing in my code:

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")

This takes 16 seconds on my machine. An equivalent C++ program takes .002 seconds.

like image 688
Taylor Avatar asked Jan 23 '17 22:01

Taylor


1 Answers

The problem is the way you're testing. No speed test in a Debug build is meaningful in the slightest. This is why you should always profile in Instruments. It uses a Release build. For realistic results, profile in Instruments on a device. Everything else is an illusion.

So do a Release build, not a Debug build. You will see that in reality you get both print statements instantly.

Results (on my computer, not a device, because I was too lazy to take the phone out of my pocket) displaying seconds since reference date:

starting 506917910.056674
done appending 506917910.060245
done 506917910.069827
like image 187
matt Avatar answered Sep 23 '22 09:09

matt