I was comparing implementations of aerial distance:
module GeoCalculator EARTH_RADIUS_IN_KM = 6371.0 def self.aerial_distance(from, to) dlat = to.lat - from.lat dlon = to.lon - from.lon a = Math.sin(dlat/2.0)**2 a += Math.cos(from.lat)*Math.cos(to.lat)*(Math.sin(dlon/2.0)**2) c = 2*Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) c*EARTH_RADIUS_IN_KM end end
Point as a struct
struct Point getter :lat, :lon def initialize(lat : Float32, lon : Float32) @lat = lat @lon = lon end end
and also as a class
class Point getter :lat, :lon def initialize(lat : Float32, lon : Float32) @lat = lat @lon = lon end end
Now, take this loop:
barcelona = Point.new(0.7223056104952821, 0.037933055776014836) paris = Point.new(0.8527087582226643, 0.04105401863784605) 1_000_000.times do GeoCalculator.aerial_distance(barcelona, paris) end
and compile with
--release (don’t know if that is relevant).
To my surprise, the loop runs about 3x faster with the struct.
As you see, instances are created once before entering the loop, and the majority of the method is trigonometry.
Where does the 3x come from?