2021年5月2日星期日

Swift Array firstIndex takes 20 seconds when matching 2 small arrays of structures

I'm using swift/swiftui to assign an structure form one array to an attribute of another structure array. The arrays are fairly small. The figureArray is about 4000 records and the specificsArray is about 200 records. The lookup match firstIndex takes about 20 seconds. Even if I comment out the assignment of specifics to the figureArray, the process takes 20 seconds, which suggests that the firstIndex in a for/forEach is extremely slow.

The memory for the process is about 90M on my iPhone 8 and the CPU hits ~100%

Question is, how can I make it faster? (much faster - i.e., less than 2 seconds). To me it seems like this process should take milliseconds for the array sizes.

The specifics objects are unique and never overlap, therefore the setting can be done in parallel. I'm just not sure how.

specificsArray.forEach { specific in      // look for a figure      if let indexFigure = figureArray.firstIndex(where: {$0.figureGlobalUniqueId == specific.specificsFirebase.figureGlobalUniqueId}) {          figureArray[indexFigure].specifics = specific      }  }  

I've also tried the following. The timing is almost identical at about 20 seconds

for indexSpecifics in 0 ..< specificsArray.count {      // look for a figure      if let indexFigure = figureArray.firstIndex(where: {$0.figureGlobalUniqueId == specificsArray[indexSpecifics].specificsFirebase.figureGlobalUniqueId}) {          figureArray[indexFigure].specifics = specificsArray[indexSpecifics]      }  }  

Specific structure

struct Specifics: Hashable, Codable, Identifiable {      var id: UUID      var specificsFirebase: SpecificsFirebase      var isSet = false  }    struct SpecificsFirebase: Hashable, Codable, CustomStringConvertible {      let seriesUniqueId: String      let figureGlobalUniqueId: String      var loose_haveCount: Int = 0      var loose_sellCount: Int = 0      var loose_wantCount: Int = 0      var new_haveCount: Int = 0      var new_orderCount: Int = 0      var new_orderText: String = ""      var new_sellCount: Int = 0      var new_wantCount: Int = 0      var notes: String = ""      var updateDate: String = ""            // print description      var description: String {          return ("SpecificsStruct: \(seriesUniqueId), \(figureGlobalUniqueId), \n  LOOSE: Have \(loose_haveCount), sell \(loose_sellCount), want \(loose_wantCount) \n  NEW: Have \(new_haveCount), sell \(new_sellCount), want \(new_wantCount), order \(new_orderCount) \(new_orderText) \n  notes \(notes), update date \(updateDate)")      }            func saveSpecifics(userID: String) {          setFirebaseSpecifics(userID: userID)      }            func setFirebaseSpecifics(userID: String) {          let firebaseRef: DatabaseReference! = Database.database().reference()          let specificsPath = SpecificsFirebase.getSpecificsFirebaseRef(userID: userID, seriesUniqueId: SeriesUniqueIdEnum(rawValue: seriesUniqueId)!,                                                                        figureGlobalUniqueId: figureGlobalUniqueId)                    let dateFormatter = DateFormatter()          dateFormatter.dateFormat = kDateFormatDatabase // firebase 2020-09-13T14:34:47.336          let updateDate = Date()          let updateDateString = dateFormatter.string(from: updateDate)            let firebaseSpecifics = [              "figureGlobalUniqueId": figureGlobalUniqueId,              "loose_haveCount": loose_haveCount,              "loose_sellCount": loose_sellCount,              "loose_wantCount": loose_wantCount,              "new_haveCount": new_haveCount,              "new_orderCount": new_orderCount,              "new_orderText": new_orderText,              "new_sellCount": new_sellCount,              "new_wantCount": new_wantCount,              "notes": notes,              "seriesUniqueId": seriesUniqueId,              "updateDate": updateDateString          ] as [String: Any]            //        #if DEBUG  //        print("Setting firebase specifics for \(firebaseSpecifics)")  //        

没有评论:

发表评论