LINQ-запрос на ConcurrentDictionary из 19710 элементов медленно - PullRequest
1 голос
/ 04 октября 2010

У меня есть следующий метод:

    /// <summary>
    /// Calculates the last trade date.
    /// </summary>
    /// <param name="tradesDictionary">The trades dictionary.</param>
    /// <returns>The last trade date.</returns>
    public DateTime CalculateLastTradeDate(ConcurrentDictionary<Guid, TradeRecord> tradesDictionary)
    { 
        // Calculate the last trade date
        _lastTradeDate = (from tradeRecord in tradesDictionary
                          where (tradeRecord.Value.OrderRecord.PairRecord.Id == _pairId)
                          select tradeRecord.Value.Date)
                         .Max();
        // Return _lastTradeDate
        return _lastTradeDate;
    }

, который занимает + - 129 секунд , то есть + - 2 минуты для выполнения на ConcurrentDictionary 21353 объектов в памяти.Могу ли я что-нибудь сделать в запросе, реализованном вышеописанным способом, чтобы значительно сократить время его выполнения?

Любая помощь будет принята!

Ответы [ 3 ]

1 голос
/ 04 октября 2010
TradeRecord.OrderRecord.PairRecord

Похоже, здесь задействованы три уровня записей базы данных. Вы на 100% уверены, что все записи находятся в памяти? Вы проверили, установив свойство log вашего datacontext или проверив профилировщик SQL?

1 голос
/ 04 октября 2010

Ну, первое, что нужно отметить, это то, что вы не действительно выполняете большую часть запроса для ConcurrentDictionary или всего, что с ним связано. Вы делаете это на копии значений, в списке.

Моим первым портом захода было бы выяснить, куда идет время - отделить вызов tradesDictionary.Values.ToList() от остальной части запроса. Хотя через 4 минуты звучит way . После того, как вы определились, какая часть вызывает проблему, я бы рассмотрел использование непараллельного запроса только для сравнения.

Кроме того, это действительно зависит от того, что делают различные свойства записей. Они обращаются к базе данных или что-то в этом роде? Кажется, ваш компьютер простаивает в течение этих четырех минут или работает на полную мощность?

Меня поражает, что на самом деле не нужно для заказа всего набора - вам просто нужно найти минимальное значение. Однако, это должно принимать только сложность от O (n log n) до O (n), и это относительно сложно сделать в «нормальном» LINQ to Objects или Parallel LINQ.

0 голосов
/ 04 октября 2010

Из приведенной здесь информации мне кажется, что максимальная дата сделки может быть более эффективно достигнута путем простого запроса базы данных.

SELECT MAX(TradeRecordTable.Date) AS MaxTradeDate
FROM   <appropriate table join>
WHERE  PairRecordTable.Id = _pairId

Если количество совпадающих строк в PairRecordTable невелико, это должно выполняться очень быстро. Я понимаю, что есть много причин, по которым это не может быть решением для вас. Но я также часто видел, как простое решение упускается из виду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...