У меня есть n слоев классов, представляющих хранилища данных, в которых хранится значение, указанное в кортеже DateTime
и TimeSpan
. Назначение «слоев» как механизм кеширования; самый нижний слой - это медленный источник данных, а самый верхний слой служит в качестве быстрого кеша в памяти.
Думайте об этих слоях как о группе: класс-обертка группы получает запрос значений между временем x и y. Сначала он создает список временных интервалов, представляющих диапазон времени между x и y, а затем вызывает каждый слой по очереди, чтобы получить значения для этих временных интервалов.
На данный момент у меня это достаточно неплохо работает, используя HashSet<T>
временных интервалов. Во-первых, самый верхний слой запрашивается для соответствия результатов, пройдя этот HashSet<T>
. Для каждого возвращаемого слота я вызываю Remove()
на HashSet<T>
.
Далее, слой, находящийся ниже, называется с тем же (но теперь потенциально меньшим) HashSet<T>
. И так далее, так что каждый слой должен выполнять только те временные интервалы, которые еще не были загружены провайдером дальше в стеке.
Причина такой многоуровневой структуры состоит в том, чтобы автоматически «заполнение» любых пропущенных временных интервалов в данных. Слой кэша в памяти должен быть свободен для освобождения памяти по мере необходимости, но заполнить пробелы путем загрузки из слоев ниже при повторном запросе данных.
В профилировании производительности конструктор HashSet<T>
(где он должен проверять уникальность исходной последовательности временных интервалов), а последующие вызовы Remove()
представляют около 45% издержек по сравнению с простым вызовом провайдера в памяти непосредственно за пределами параметра группы.
Есть ли другой решение такой проблемы? Другой способ думать о моей цели состоит в том, что у меня есть Dictionary<(DateTime, TimeSpan), TValue>
, и я многократно пытаюсь найти, какие значения пропущены как можно быстрее на миллионах клавиш.
Большое спасибо заранее!