LINQ操作缓慢
本文关键字:缓慢 操作 LINQ | 更新日期: 2023-09-27 18:23:55
我有以下代码:
public static IEnumerable<int> GetCloseZipCodes(int zipcode, int radius)
{
PycDBDataContext db = new PycDBDataContext();
ZipCode reqZipInfo = ZipCodes.Instance.zipcodes[zipcode];
if (reqZipInfo == null)
return new int[] { };
double longt = LongitudePlusDistance((double)reqZipInfo.Longitude, (double)reqZipInfo.Latitude, radius);
double latit = LatitudePlusDistance((double)reqZipInfo.Latitude, radius);
double minLong = 2 * (double)reqZipInfo.Longitude - longt;
double minLat = 2 * (double)reqZipInfo.Latitude - latit;
var zips = ZipCodes.Instance.zipcodes.Where(x => (double)x.Value.Longitude >= minLong &&
(double)x.Value.Longitude <= longt &&
(double)x.Value.Latitude >= minLat &&
(double)x.Value.Latitude <= latit &&
CalcDistance((double)reqZipInfo.Longitude,
(double)reqZipInfo.Latitude,
(double)x.Value.Longitude,
(double)x.Value.Latitude) <= radius).Select(x => x.Key);
return zips;
}
这个函数有一个邮政编码,一个半径,它会找到半径内的所有邮政编码。我在这里遇到了性能问题,在运行dotTrace之后,我的大部分时间都在以下方面:
var zips = ZipCodes.Instance.zipcodes.Where(x => (double)x.Value.Longitude >= minLong &&
(double)x.Value.Longitude <= longt &&
(double)x.Value.Latitude >= minLat &&
(double)x.Value.Latitude <= latit &&
CalcDistance((double)reqZipInfo.Longitude,
(double)reqZipInfo.Latitude,
(double)x.Value.Longitude,
(double)x.Value.Latitude) <= radius).Select(x => x.Key);
三分之一的时间,它正在访问
public System.Nullable<decimal> Longitude
{
get
{
return this._Longitude;
}
set
{
if ((this._Longitude != value))
{
this._Longitude = value;
}
}
}
如何提高性能???我们在这里谈论几秒钟。。。我不明白为什么。这都是缓存的并且不是SQL。
首先,据我所见,您正在double
和decimal
之间进行大量转换。
我建议要么将对象表示更改为使用double
开头,要么
除此之外,保持一个一致的表示将使您的代码更干净,并且可能性能更好。在这种情况下,我想说double
可能比decimal
更合适——它们不像货币那样是精确的十进制值;它们是自然出现的值,已经通过测量进行了近似。
此外,您还多次执行可为null到不可为null的转换,这两次都是针对x.Value
和进行比较。请考虑使用lambda语句:
x => {
if (x.Longitude == null || x.Latitude == null)
{
return false;
}
double longitude = x.Value.Longitude.Value;
double latitude = x.Value.Latitude.Value;
return longitude >= minLong &&
longitude <= longt &&
latitude >= minLat &&
latitude <= latit &&
longitude >= minLong &&
CalcDistance(reqZipInfo.Longitude, reqZipInfo.Latitude,
longitude, latitude) <= radius;
}
为了可读性,老实说,我可能会把它放在一个单独的方法中。
(顺便说一句,你甚至需要属性可以为null吗?这对我来说没有多大意义。)