1

I am making an application where in a table View i want to show to the user places from the closest to the farest. I am using this function to calculate the distance between the user location and these places :

var distanceToUsersCurrentLocation: Double {
    let manager = CLLocationManager()
    let destinationCoordinates = CLLocation(latitude: (self.getLat() as NSString).doubleValue, longitude: (self.getLon() as NSString).doubleValue)
    let selfCoordinates = CLLocation(latitude: (manager.location?.coordinate.latitude)!, longitude: (manager.location?.coordinate.longitude)!)
    return selfCoordinates.distance(from: destinationCoordinates) 

And now to sort my array I am using this function :

self.ListeChantiers?.sort(by: {ji,jij in ji.distanceToUsersCurrentLocation.isLess(than:jij.distanceToUsersCurrentLocation)})

This is working but the problem is that it's taking way too much time. Can someone tell me if it's mandatory or if there is a quicker solution ? Thanks for reading (and maybe helping) !

  • `(self.getLat() as NSString).doubleValue` So many questions. 1) why do you have a `getLat()` function, instead of a computed property? 2) Why does `getLat/Long()` return `String` and not `Double`? 3) Why are `getLat/Long()` split, when there could just be one computed property for `destinationLocation`? – Alexander Aug 29 '18 at 02:41
  • 1) I'm new to swift and learned programmation with Java so all the properties of my classes are private.. Maybe it's useless ? 2) Because I receive these values from an HTTP request as JSON and when I use codable the parameters have to be Strings 3) Because I get them splitted but yes I can join them, will this make me earn some time ? Thank you for your answer – Victor Aguer Aug 29 '18 at 03:48
  • 1) The java setter/getter convention is an anti-pattern in Swift. In java, it exists to decouple interface from storage. Something that's a mere getter of an instance variable could be refactored in the future to be some calculation, some api call, etc., with no change of interface. In Swift, properties achieve this. There are no true instance variables. The same future proofing is possible, because a stored property can be replaced with a computed property, with no change in interface. – Alexander Aug 29 '18 at 04:09
  • 2) handle the String to double parsing at the codable layer. Don't let it leek through your entire code base. https://stackoverflow.com/a/46901708/3141234 The general rule of thumb is to deserialize fully as early as possible, and serialize as late as possible, so that your serialization/deserialization is maximally confined to those 2 simple points in time. 3) "earn some time"? – Alexander Aug 29 '18 at 04:10
  • Not related to your question but why not simply `let selfCoordinates = manager.location!`? – Leo Dabus Aug 29 '18 at 04:57

1 Answers1

2

Computing the distance between lat/long pairs is pretty time-consuming. Your code is repeating that conversion twice for every comparison. Don't do that. For a really good sort algorithm, that will convert your lat/long pairs to distances about 2•n•log(n) times

Is your var distanceToUsersCurrentLocation a property of the objects in your array? If so, change it to be a lazy var. That way, it will be computed the first time you need it and then treated as a constant thereafter.

In order to use a lazy var, your object will need to be a class, not a struct (a reference type, not a value type.)

If your data object is a struct and you can't change it to class, you might need to map your array of structs to an array of tuples of type (Chantier, Double), sort the array of tuples, and maps that resulting array back an array of Chantier objects

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Hello , thank you for your answer ! No it's not a property of my "chantier" class but I can create a property and a Set function and instantiate this property for all my objects in the viewdidload and then work on this property ? The time that my View will take to load will grow but the sort function's time will be reduced ? – Victor Aguer Aug 29 '18 at 03:54
  • Okay tested it : went from 1 minute to 2 seconds of execution ! Thanks a lot – Victor Aguer Aug 29 '18 at 04:16