慢LINQ操作

时间:2012-02-10 07:22:26

标签: c# asp.net linq

我有以下代码:

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;
        }

此函数带有一个zipcode,一个半径,它将找到半径内的所有zipcodes。 我在这里遇到了性能问题,在运行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。

1 个答案:

答案 0 :(得分:3)

首先,就我所见,您在doubledecimal之间进行了很多次转化。

我建议 更改对象表示以使用double开头,转换longtlatitdecimal,以便您可以在单一类型中执行所有比较,而无需进行所有转换。

除了其他任何内容,保持一致的表示将使您的代码更清洁并且可能表现更好。在这种情况下,我会说double可能是一个比decimal更合适的表示 - 它不像是精确十进制值,如货币;它们是自然发生的值,已经通过测量近似。

此外,您可以对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;
}

为了便于阅读,我可能会把它放在一个单独的方法中,说实话。

(顺便说一句,你甚至需要属性可以为空吗?对我来说没什么用。)