I am having the following code:
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;
}
This function is given with a zipcode, a radius and it will find all the zipcodes within the radius.
I have performance issues here and after running dotTrace most of my time is in the following:
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);
And third of the time there, it is accessing
public System.Nullable<decimal> Longitude
{
get
{
return this._Longitude;
}
set
{
if ((this._Longitude != value))
{
this._Longitude = value;
}
}
}
How can I improve the performance??? We are talking about a few seconds here…
I can’t understand why. this is all cached and non-SQL.
For one thing, you’re doing a lot of conversions between
doubleanddecimalas far as I can see.I’d suggest either changing your object representation to use
doubleto start with, or convertlongtandlatittodecimalso that you can perform all the comparisons in a single type, without all the conversions.Aside from anything else, keeping one consistent representation will leave your code cleaner as well as probably performing better. In this case, I’d say that
doubleis probably a more appropriate representation thandecimalanyway – it’s not like these are exact decimal values like currency; they’re naturally-occurring values which have already been approximated by measurement.Additionally, you’re doing the nullable to non-nullable conversion several times, both for
x.Valueand for comparisons. Consider using a statement lambda instead:For the sake of readability, I’d probably put this in a separate method to be honest.
(Do you even need the properties to be nullable, by the way? It doesn’t make much sense to me.)