Sahil Srivastava
Sahil Srivastava

Reputation: 85

SwiftUI Large Array (over 30K elements) taking forever to iterate over

I'm so confused as to what's going on but basically, this is my code. Maybe I just am stupid or do not enough above swift or something but I feel like this should take less than a second, but it takes a very long time to iterate through (i added the CFAbsoluteTimeGetCurrent) because I wanted to see how long each assignment took and they take around 0.0008949041366577148 seconds each, but over the span of 30K that adds up obviously. This is just test code but what I'm really trying to do is implement Agglomerative Clustering using a single linkage in Swift, at first I thought that my algorithm was written poorly but then I just tried to iterate over an array like this and it still took a long time. Does anyone know what's up?

I'm also aware that printing out statements in the console takes time but even after removing these statements the onAppear closure still took a while to finish.

Also sorry this is my first time ever posting on Stack Overflow so if please let me know if I should write my posts a certain way in the future.

    @State private var mat: [Double?] = Array(repeating: nil, count: 30000)
    
    var body: some View {
        Text("HELLo")
            .onAppear() {
                for i in 0..<matrix.count {
                    let start = CFAbsoluteTimeGetCurrent()
                    mat[i] = 0
                    let diff = CFAbsoluteTimeGetCurrent() - start
                    print("HAC_SINGLELINK.init TIME: \(diff), ROW \(i) of \(matrix.count)")
                  }
                    
                }
            }

Upvotes: 4

Views: 744

Answers (1)

jnpdx
jnpdx

Reputation: 52387

I believe the time is caused by the number of modifications you do to your @State variable, which cause a lot of overhead.

With your initial code, on my machine, it took ~16 seconds. With my modified code, which does all of the modifications on a temporary non-state variable and then assigns to @State once, it takes 0.004 seconds:

.onAppear() {
    let start = CFAbsoluteTimeGetCurrent()
    
    var temp = matrix
    
    for i in 0..<temp.count {
        temp[i] = 0
    }
    let diff = CFAbsoluteTimeGetCurrent() - start

    matrix = temp
    
    print("HAC_SINGLELINK.init TIME: \(diff) \(matrix.count)")
                    
}

Upvotes: 3

Related Questions