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
```

Defined a `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?