Что является самым эффективным способом создать кэш с произвольными объектами Ruby как ключи, которые истекают на основе последнего использованного алгоритма. Это должно использовать нормальную семантику хеширования Ruby (не равный?)
Это раздвигает границы моего понимания того, как Ruby использует память, но я подозреваю, что наиболее эффективной реализацией будет двусвязный список, в котором каждый доступ перемещает ключ в начало списка. , и каждая вставка отбрасывает элемент, если был достигнут максимальный размер.
Однако, если предположить, что класс Ruby Hash
уже очень эффективен, я готов поспорить, что несколько наивное решение простого добавления данных о возрасте в Хэш
было бы неплохо. Вот небольшой игрушечный пример, который делает это:
class Cache
attr_accessor :max_size
def initialize(max_size = 4)
@data = {}
@max_size = max_size
end
def store(key, value)
@data.store key, [0, value]
age_keys
prune
end
def read(key)
if value = @data[key]
renew(key)
age_keys
end
value
end
private # -------------------------------
def renew(key)
@data[key][0] = 0
end
def delete_oldest
m = @data.values.map{ |v| v[0] }.max
@data.reject!{ |k,v| v[0] == m }
end
def age_keys
@data.each{ |k,v| @data[k][0] += 1 }
end
def prune
delete_oldest if @data.size > @max_size
end
end
Вероятно, есть более быстрый способ найти самый старый элемент, и он не был тщательно протестирован, но мне было бы любопытно узнать, как кто-то думает, что это по сравнению с более сложным дизайном, связанным список или иначе.
Remaze has a reasonably well tested LRU Cache: See http://github.com/manveru/ramaze/blob/master/lib/ramaze/snippets/ramaze/lru_hash.rb
And there is also the hashery
gem by rubyworks which should be more efficient than the remaze one for large caches.