在我的之前的问题中,我试图根据函数结果加速列表选择。现在,我的瓶颈是函数本身。
这是一个基本的Haversine函数,使用下面的代码:
private static double Haversine(double lat1, double lat2, double lon1, double lon2)
{
const double r = 6371e3; // meters
var dlat = (lat2 - lat1)/2;
var dlon = (lon2 - lon1)/2;
var q = Math.Pow(Math.Sin(dlat), 2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Pow(Math.Sin(dlon), 2);
var c = 2 * Math.Atan2(Math.Sqrt(q), Math.Sqrt(1 - q));
var d = r * c;
return d / 1000;
}
所以...为什么需要这么快呢?问题在于我会频繁地调用它。想象一下超过16,500,000次。
显然,这是非常多的。而且在我的使用情况下,我要传递对象给它,然后将纬度和经度转换为弧度,这进一步增加了时间(只增加了约15%)。我不知道有什么可以做的,但我知道如果像上面那样只传递纯双精度数值,需要大约4.5秒 - 这已经占据了我实现中处理时间的75%以上。赋值给q和c的行似乎占用了最多的时间。
由于频繁地调用它,我希望使它变得更快一些。我接受多线程解决方案(并且目前正在自己开发一个),但考虑到我之前的问题的使用情况(链接如上),实现起来可能会更加困难。
d = 2 * r * Math.Asin(Math.Sqrt(h));
,因此可以消除调用Math.Sqrt
这个问题,这将有助于提高性能。然而,我认为你的整体设计可能存在更大的问题。在另一个问题的评论中,你提到需要为500个邮政编码调用33,000次Haversine
(这就是16,500,000来自哪里)。首先,为什么要这样做?其次,这种设置(假设邮政编码彼此引用)正好适合使用查找表。 - Abion47