Qual è il modo più efficiente per creare una cache con oggetti Ruby arbitrari come chiavi scadute in base a un algoritmo meno recente utilizzato. Dovrebbe utilizzare la normale semantica dell'hash di Ruby (non uguale?)Efficient Ruby LRU cache
risposta
Questo spinge i limiti della mia comprensione di come Ruby utilizza la memoria, ma sospetto che l'implementazione più efficiente sarebbe una lista doppiamente collegata in cui ogni accesso sposta la chiave in primo piano nell'elenco e ogni inserto rilascia un articolo se è stata raggiunta la dimensione massima.
Tuttavia, supponendo che la classe Hash
di Ruby sia già molto efficiente, scommetterei che la soluzione un po 'ingenua di aggiungere semplicemente dati di età a un Hash
sarebbe abbastanza buona. Ecco un esempio di giocattoli rapida che fa questo:
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
C'è probabilmente un modo più veloce di trovare l'oggetto più antico, e questo non è testato, ma sarei curioso di sapere come qualcuno pensa questo a fronte di un maggiore design sofisticato, elenco collegato o altro.
delete_oldest sia O (n) che è inefficiente, puoi farlo in tempo costante se usi un'altra implementazione – Noam
Il blog di Ruby Best Practices ha uno post.
Remaze ha un ragionevolmente ben collaudato LRU cache: Vedere http://github.com/manveru/ramaze/blob/master/lib/ramaze/snippets/ramaze/lru_hash.rb
E c'è anche il hashery
gemma da rubyworks che dovrebbe essere più efficiente rispetto alla remaze uno per i grandi cache.
gem install ruby-cache
La gemma rufus-LRU è un'altra opzione.
Invece di un conteggio solo mantiene un array ordinato di chiavi dal più vecchio al più recente
ho buttato insieme un nuovo gioiello lrucache che si possono trovare utili. Potrebbe essere più veloce dell'approccio di Alex per le collezioni con un numero significativo di elementi.
molto semplice e veloce di cache LRU che uso nel nostro backend http https://github.com/grosser/i18n-backend-http/blob/master/lib/i18n/backend/http/lru_cache.rb
Questo link è ora rotto. –
Thx, contento di averlo già usato in un progetto :) – grosser
So che è un paio di anni di ritardo, ma ho appena realizzato quello che credo sia il più veloce LRU cache là fuori per Ruby.
È inoltre testato e opzionalmente sicuro da utilizzare in ambienti con più thread.
https://github.com/SamSaffron/lru_redux
Nota: in Ruby 1.9 Hash è ordinato, in modo da poter imbrogliare e costruire la cache LRU più veloce in poche righe di codice
class LruRedux::Cache19
def initialize(max_size)
@max_size = max_size
@data = {}
end
def max_size=(size)
raise ArgumentError.new(:max_size) if @max_size < 1
@max_size = size
if @max_size < @data.size
@data.keys[[email protected][email protected]].each do |k|
@data.delete(k)
end
end
end
def [](key)
found = true
value = @data.delete(key){ found = false }
if found
@data[key] = value
else
nil
end
end
def []=(key,val)
@data.delete(key)
@data[key] = val
if @data.length > @max_size
@data.delete(@data.first[0])
end
val
end
def each
@data.reverse.each do |pair|
yield pair
end
end
# used further up the chain, non thread safe each
alias_method :each_unsafe, :each
def to_a
@data.to_a.reverse
end
def delete(k)
@data.delete(k)
end
def clear
@data.clear
end
def count
@data.count
end
# for cache validation only, ensures all is sound
def valid?
true
end
end
- 1. LRU cache design
- 2. Implementazione della cache LRU in Javascript
- 3. Python: la costruzione di una cache LRU
- 4. Implementazione standard di una cache LRU
- 5. Usa LinkedHashMap per implementare la cache LRU
- 6. Efficient Python Daemon
- 7. Ordinato dizionario ordinato sul valore in C# (cache LRU)
- 8. Ruby object cache
- 9. Redis maxmemory-policy: prestazioni di volatile-lru vs allkeys-lru
- 10. Implementazione LRU nel codice di produzione
- 11. Memcached LRU e scadenza
- 12. Dimensionamento della cache LRU in base alle funzionalità del dispositivo e alla memoria disponibile
- 13. Come posso rendere la mia semplice cache LRU .NET più veloce?
- 14. Quali strutture dati vengono comunemente utilizzate per le cache LRU e per localizzare rapidamente gli oggetti?
- 15. ConcurrentModificationException durante l'aggiornamento di Iterator memorizzato (per l'implementazione della cache LRU)
- 16. Ruby on Rails - La transazione contro-cache è sicura?
- 17. Come posso memorizzare in cache un metodo con Ruby/Rails?
- 18. Concorrenza alta frequente per la cache
- 19. Hibernate cache di secondo livello
- 20. cache di libreria per Objective-C (iPhone)
- 21. Domanda cache cache SQL
- 22. EhCache + Hibernate Cache non è attivo
- 23. Politica di sfratto della cache di Guava
- 24. Dove ottenere i dati per confrontare gli algoritmi di cache
- 25. locale Cache Biblioteca C# (persistente e criptato)
- 26. Scarse prestazioni con Guava Cache su Android
- 27. Magento cache - Regola per pulire la cache
- 28. Browser Cache Vs HTML5 Application Cache
- 29. Jersey: Controllo cache predefinito su no-cache
- 30. Come implementare un in Memory Image Cache in Android?
Stai cercando per l'utilizzo di memoria minimo o uso minimo della CPU, quanto spesso stai facendo uscire della cache LRU? Puoi scegliere l'approccio scavenger o un doppio elenco collegato con un hash accoppiato. –
per alcune idee: http://java.sun.com/j2se/1.4.2/docs/api/java/util/LinkedHashMap.html anche mongodb ha la collezione ridotta in modo analogo, è possibile eseguire questa operazione con i redis.supponendo che tu stia cercando una soluzione rubino integrata sebbene –