¿Cuál es la forma más eficiente de construir un caché con objetos de Ruby arbitrarios como claves caducadas en función de un algoritmo utilizado menos recientemente? Debería usar la semántica de hashing normal de Ruby (¿no es igual?)Caché de LRU de Ruby eficiente
Respuesta
Esto traspasa los límites de mi comprensión de cómo Ruby usa memoria, pero sospecho que la implementación más eficiente sería una lista doblemente enlazada donde cada acceso mueve la tecla al frente de la lista, y cada inserción deja caer una artículo si se alcanzó el tamaño máximo.
Sin embargo, suponiendo que la clase Hash
de Ruby ya es muy eficiente, apostaría a que la solución ingenua de simplemente agregar datos de edad a un Hash
sería bastante buena. He aquí un ejemplo de juguete rápida que hace esto:
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
Probablemente hay una manera más rápida de encontrar el elemento más antiguo, y esto no ha sido probada, pero tengo curiosidad de saber cómo alguien piensa que esto se compara con una mayor diseño sofisticado, lista vinculada o de lo contrario.
delete_oldest es O (n) que es ineficiente, puede hacerlo en tiempo constante si usa otra implementación – Noam
El blog Ruby Best Practices tiene un post al respecto.
Remaze tiene un caché LRU razonablemente bien probado: Ver http://github.com/manveru/ramaze/blob/master/lib/ramaze/snippets/ramaze/lru_hash.rb
Y también existe la hashery
joya por rubyworks que debería ser más eficiente que el Remaze uno para grandes cachés.
gem install ruby-cache
La gema rufus-LRU es otra opción.
En lugar de un recuento que sólo mantiene un arreglo ordenado de las llaves del más antiguo al más reciente
Tiré juntos una nueva joya lrucache que pueden serle de utilidad. Puede ser más rápido que el enfoque de Alex para las colecciones con un número significativo de elementos.
muy simple y rápida caché LRU utilizo en nuestro back-end http https://github.com/grosser/i18n-backend-http/blob/master/lib/i18n/backend/http/lru_cache.rb
Este enlace ahora está roto. –
Thx, me alegro de que ya lo usé en un proyecto :) – grosser
Sé que es un par de años de retraso, pero simplemente implementa lo que creo que es el más rápido caché LRU por ahí para Ruby.
También se ha probado y, opcionalmente, es seguro para su uso en entornos de múltiples hilos.
https://github.com/SamSaffron/lru_redux
Nota: en Ruby se ordena 1,9 Hash, por lo que puede engañar y construir el caché LRU más rápido en unas pocas líneas de código
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. Diseño de memoria caché LRU
- 2. Caché LRU fácil de usar en java
- 3. LRU byte Cache java
- 4. Python: la construcción de una memoria caché LRU
- 5. Diccionario ordenado según el valor en C# (caché LRU)
- 6. ¿Hay alguna implementación LRU de IDictionary?
- 7. Implementación de LRU en el código de producción
- 8. Memrached LRU y expiración
- 9. Tamaño LRU Caché de acuerdo con las capacidades del dispositivo y la memoria libre
- 10. ¿Qué significa en realidad LRU de Memcached?
- 11. Caché eficiente y BLOB's - caché de creación de perfiles aciertos/errores
- 12. ¿Cómo puedo hacer que mi caché. LRU simple sea más rápido?
- 13. LRU LinkedHashMap que limita el tamaño según la memoria disponible
- 14. ¿Qué estructuras de datos se usan comúnmente para las memorias caché LRU y la ubicación rápida de objetos?
- 15. Caché genérica de objetos
- 16. Error de caché del contador de Ruby on Rails
- 17. Cómo caché JSON en ruby on rails?
- 18. Hibernate caché de segundo nivel
- 19. ¿Cómo elimino el caché de Ruby Phusion Passenger en Ubuntu?
- 20. Ruby on Rails: ¿Es segura una transacción de contra-caché?
- 21. biblioteca de caché para Objective-C (iPhone)
- 22. caché de predicados
- 23. Cómo almacenar y leer una jerarquía de manera eficiente desde el caché
- 24. ¿Cómo guardo en caché un método con Ruby/Rails?
- 25. ¿Forma más eficiente de Ruby de asignar atributos en una matriz de objetos a otra matriz?
- 26. ¿Qué algoritmo de almacenamiento en caché usa NSURLCache?
- 27. ¿La manera más eficiente de calcular la distancia de hamming en ruby?
- 28. ¿Cómo puedo eliminar de manera eficiente el flotante cero negativo de Ruby?
- 29. Cómo crear una lista de números y anexarla inversamente de manera eficiente en Ruby
- 30. Ehcache caché por defecto en Java
¿Estás tratando para su uso mínimo de memoria o el uso mínimo de la CPU, ¿con qué frecuencia está sacando cosas de la memoria caché LRU? Puede elegir el enfoque de carroñero o una lista de doble enlace con un hash emparejado. –
para ver algunas ideas, vea: http://java.sun.com/j2se/1.4.2/docs/api/java/util/LinkedHashMap.html también mongodb ha limitado la colección de forma similar, puede hacer esto con redis.suponiendo que está buscando una solución de rubí incorporada aunque –