from math import radians, cos, sin, asin, sqrt import numpy as np import random import time from functools import wraps import time from functools import wraps def get_lat(): return random.uniform(-90, 90) def get_long(): return random.uniform(-180, 180) def benchmark(function): @wraps(function) def wrapper(*args, **kwargs): times = [] res = None N_times = 100_000 for _ in range(100_000): start = time.time() res = function(*args, **kwargs) end = time.time() delta = end - start times.append(delta) total = sum(times) avg = total / N_times print(f'total: {sum(times):.6f}') print(f'avg: {avg:.6f}') return res return wrapper def get_distance(start_point: tuple[float, float], end_point: tuple[float, float]) -> float: """ Calculate the distance between two geographical locations in kilometers. :param start_point: A tuple containing the latitude and longitude of the starting point. :param end_point: A tuple containing the latitude and longitude of the ending point. :return: The distance between the two points in kilometers. """ # Convert degrees to radians start_lat = radians(start_point[0]) start_lon = radians(start_point[1]) end_lat = radians(end_point[0]) end_lon = radians(end_point[1]) # Haversine formula dlon = end_lon - start_lon dlat = end_lat - start_lat a = sin(dlat / 2) ** 2 + cos(start_lat) * cos(end_lat) * sin(dlon / 2) ** 2 c = 2 * asin(sqrt(a)) # Calculate distance in kilometers earth_radius = 6371 distance = earth_radius * c return distance def get_distances_multiple(start_point: tuple[float, float], end_points: list[tuple[float, float]]) -> np.array: """ Calculate the distances between a starting point and multiple ending points in kilometers. :param start_point: A tuple containing the latitude and longitude of the starting point. :param end_points: A list of tuples containing the latitude and longitude of the ending points. :return: An array of distances between the starting point and each ending point in kilometers. """ # Convert degrees to radians start_lat = radians(start_point[0]) start_lon = radians(start_point[1]) end_lats = np.array([radians(end_point[0]) for end_point in end_points]) end_lons = np.array([radians(end_point[1]) for end_point in end_points]) # Haversine formula dlon = np.subtract(end_lons, start_lon) dlat = np.subtract(end_lats, start_lat) a = np.sin(dlat / 2) ** 2 + np.cos(start_lat) * np.cos(end_lats) * np.sin(dlon / 2) ** 2 c = 2 * np.asin(np.sqrt(a)) # Calculate distance in kilometers earth_radius = 6371 distances = earth_radius * c return distances def main(): points = [ (get_lat(), get_long()) for _ in range(1000) ] target = random.choice(points) @benchmark def test1(): result_1 = [get_distance(target, a) for a in points] return result_1 @benchmark def test2(): result_2 = get_distances_multiple(target, points) return result_2 res_1 = test1() res_2 = test2() comp = res_1 == res_2 print(f'Same: ', len(list(_ for _ in comp if _ == True))) diff_values = [(a, b) for a,b in zip(res_1, res_2) if a != b] print(f'Difference: ', len(diff_values)) for a, b in diff_values: print(f'{a:>20} {b:>20}') if __name__ == '__main__': main()