1

I'm working with 919 objects. The following code finds my filtered objects in the local Realm DB, sorts them, and then constructs the result into another array.

var rowItems: [SignRowAttribute] = []

let startTime1 = CFAbsoluteTimeGetCurrent()

// collect
let additionalFilter: String = "isRemovedOnClient == false"
allSignAnnotations = (self.signAnnotationsDAL.findAllWith(listFilter.currentOrganization,
                                                          locationID: listFilter.currentLocation,
                                                          projectIDs: listFilter.allProjectIDs,
                                                          workflowStateIDs: listFilter.allWorkflowStateIDs,
                                                          withAdditionalPredicate: additionalFilter))

let timeElapsed1 = CFAbsoluteTimeGetCurrent() - startTime1
DDLogInfo("⏱ findAllWith Time: \(timeElapsed1)")


let startTime2 = CFAbsoluteTimeGetCurrent()

// Sort by:
//  1. sign number
//  2. sign type order_id
// https://stackoverflow.com/a/37604010/7599
let sortedSigns = self.allSignAnnotations.sorted(by: {

    // Pull out a copy of the object to better access its properties.
    let sign0 = RLMSignAnnotation(value: $0)
    let sign1 = RLMSignAnnotation(value: $1)

    if sign0.number != sign1.number {
        // alphanumeric sort
        // https://stackoverflow.com/a/31210070/7599
        return sign0.number.localizedStandardCompare(sign1.number) == .orderedAscending
    } else {
        if let type0 = sign0.signTypeID,
            let type1 = sign1.signTypeID {
            let signType0 = RLMSignType().find(withID: type0)!
            let signType1 = RLMSignType().find(withID: type1)!

            return signType0.orderID.localizedStandardCompare(signType1.orderID) == .orderedAscending
        }
    }

    return sign0.number.localizedStandardCompare(sign1.number) == .orderedAscending

})

let timeElapsed2 = CFAbsoluteTimeGetCurrent() - startTime2
DDLogInfo("⏱ sortedSigns Time: \(timeElapsed2)")


let startTime3 = CFAbsoluteTimeGetCurrent()

// assemble
for sign in sortedSigns {
    rowItems.append(SignRowAttribute(id: sign.id,
                                     title: sign.title,
                                     titleColor: sign.titleTextColour,
                                     backgroundColor: sign.colour,
                                     isReviewable: sign.isReviewable,
                                     reviewState: sign.reviewState!))
}

let timeElapsed3 = CFAbsoluteTimeGetCurrent() - startTime3
DDLogInfo("⏱ assemble Time: \(timeElapsed3)")

The timing results, in seconds:

⏱ findAllWith Time: 0.00439608097076416
⏱ sortedSigns Time: 2.5146470069885254
⏱ assemble Time: 0.9812660217285156

I wouldn't expect a small batch of only ~900 objects to crawl like this on an iPhone XS.

How can I get this down to sub-second performance?

Sebastian Dwornik
  • 2,526
  • 2
  • 34
  • 57
  • Have you profiled this in instruments? Where is the time going? – jrturton Nov 14 '19 at 13:58
  • 1
    There's a a lot of ambiguity in the code because we don't know what some of those functions do and those functions could be leading to long sort times. So for example, we don't know what *RLMSignType* is or does. We also don't know what *RLMSignAnnotation* is or does. There's a few things you can do to improve the question; reduce the amount of code to something that can be used to duplicate the issue. See [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). Also, having an understanding of what the Realm models look like would be a big help. – Jay Nov 14 '19 at 15:45

0 Answers0