Show HN:我构建了一个带有 TTL 的 Ruby gem 来处理记忆化
Show HN: I built a Ruby gem that handles memoization with a ttl

原始链接: https://github.com/mishalzaman/memo_ttl

MemoTTL是一个Ruby gem,提供线程安全的带生存时间 (TTL) 和最近最少使用 (LRU) 驱逐机制的记忆化功能。它能有效缓存方法的结果,避免冗余计算,从而提高性能。 主要特性包括: * **TTL:** 缓存值在指定时间后过期,确保数据新鲜度。 * **LRU 驱逐:** 通过在达到最大大小限制时自动移除最近最少访问的缓存条目来限制内存使用。 * **线程安全:** 可安全用于多线程环境。 * **易于集成:** 使用`include MemoTTL` 和 `memoize` 即可轻松集成到类中。 * **缓存管理:** 提供方法来清除特定记忆化方法、所有记忆化方法或触发清理进程。 它非常适合那些性能至关重要且需要控制内存使用的应用程序,例如缓存API响应或进行计算量大的计算。

MishalZaman 发布了一个名为 "memo_ttl" 的 Ruby gem,用于带有生存时间 (TTL) 和最近最少使用 (LRU) 缓存的记忆化。它是线程安全的,并设计为易于集成到 Ruby 应用程序中。 Hacker News 上的讨论帖提供了积极的反馈。`film42` 称赞了其基于方法的缓存方法,因为它最大限度地减少了竞争,并建议使用读写锁代替 Monitor,以获得潜在的性能提升。他们还建议不要包装被记忆化方法的错误,以保留原始堆栈跟踪以便于调试。 `locofocos` 询问了使用 `memo_ttl` 相比于 Rails.cache.fetch 使用 Redis 和 "allkeys-lru" 配置(该配置已经提供了 TTL 功能)的优势。 `qrush` 祝贺 MishalZaman 发布了这个 gem,并建议在 GitHub 代码库中添加描述,以提高其可发现性。

原文

Gem Version

MemoTTL is a thread-safe memoization utility for Ruby that supports TTL (Time-To-Live) and LRU (Least Recently Used) eviction. It's designed for scenarios where memoized values should expire after a period and memory usage must be constrained.

  • Memoize method results with expiration (TTL)
  • Built-in LRU eviction to limit memory usage
  • Thread-safe with Monitor
  • Easy integration via include MemoTTL

Add this line to your application's Gemfile:

Afterwards:

require "memo_ttl"

class Calculator
  include MemoTTL

  def a_method_that_does_something(x)
    sleep(2) # simulate slow process
    x * 2
  end

  # use at the bottom due to Ruby's top-down evalation of methods
  memoize :a_method_that_does_something, ttl: 60, max_size: 100
end

calc = Calculator.new
calc.a_method_that_does_something(5) # takes 2 seconds
calc.a_method_that_does_something(5) # returns instantly from cache

To clear the cache:

calc.clear_memoized_method(:a_method_that_does_something)
calc.clear_all_memoized_methods
calc.cleanup_memoized_methods
require 'memo_ttl'

class TestController < ApplicationController
  include MemoTTL

  def index
    result1 = test_method(1, 2)
    result2 = test_method(1, 2)
    result3 = test_method(5, 2)
    result4 = test_method(1, 2)
    result5 = test_method(1, 2)
    result6 = test_method(3, 4)

    render plain: <<~TEXT
      Result 1: #{result1}
      Result 2: #{result2}
      Result 3: #{result3}
      Result 4: #{result4}
      Result 5: #{result5}
      Result 6: #{result6}
    TEXT
  end

  def test_method(x, y)
    puts "Calling test_method(#{x}, #{y})"
    x + y
  end

  def clean_up
    clear_memoized_method(:test_method)
    clear_all_memoized_methods
    cleanup_memoized_methods
  end

  memoize :test_method, ttl: 10, max_size: 10
end

Output in Rails console:

Processing by TestController#index as HTML
Calling test_method(1, 2)
Calling test_method(5, 2)
Calling test_method(3, 4)
联系我们 contact @ memedata.com