我研究了一下memoist和Rails缓存,看哪个性能更好

我调查了一下,想知道Memoist和Rails缓存中哪个性能更好。

首先

在Rails中,即使我们在主数据库上多次执行相同的查询或者使用includes来解决N+1问题,最终可能仍会发出大型的SQL查询,效率并不高的情况也是存在的。

我试过使用一种名为memoist的方法将数据保存在内存中以便再次利用,但是我怀疑是否使用普通的Rails自带的Low-Level Caching功能也不会有太大的性能差异。因此我进行了测试,在我们运营的服务中决定选择哪种方法。

※Rails的缓存使用memcache

验证环境

    • OS: MacOSX 10.10

 

    • Rails version: 4.2

 

    memoist version: 0.12.0

样本代码

class SampleCode < ActiveRecord::Base

  #キャッシュされるSampleCodeモデルのコード群
  @@cached_codes = [AAA, BBB, CCC, DDD, EEE].map!(&:freeze).freeze

  # クラスメソッドのメモ化
  class << self
    extend Memoist
    def plan_ids
      SampleCode(code: @@cached_codes).pluck(:id)
    end
    memoize :plan_ids
  end

  # クラスメソッドで、Low-Level Cachingを利用
  def self.plan_ids_cache
    Rails.cache.fetch("plan_ids_cache_key", expires_in: 1.day) do
      SampleCode(code: @@cached_codes).pluck(:id)
    end
  end
end

测量

启动Rails控制台并将下面的验证代码复制并执行。

> bin/rails console 

获取存放了5个整数的数组的方法使用memoist的情况下和使用低级缓存的情况下,以及最后通过普通的ActiveRecord获取数据的情况下,重复1000次。

由于基准测试的执行次数书写方式有误,已经进行修正。

# 開実行する
require "benchmark"

#試行回数
num = 1000

plan_code = [AAA, BBB, CCC, DDD, EEE].map!(&:freeze).freeze

report = Benchmark.bm do |r|
  r.report "memo" do
    num.times { SampleCode.plan_ids }
  end
  r.report "cache" do
    num.times { CampaignCode.plan_ids_cache }
  end
  # ActiveRecordで素でとった場合
  r.report "ar original" do
    num.times { SampleCode.where(code: plan_code).pluck(:id) }
  end
end


# ローカル環境実行結果(memcachedもローカルサーバで動いている)
=>
            user     system   total   real
memo        0.0200   0.0100   0.0300 (0.0332)
cache       0.3299   0.2200   0.5499 (1.1794)
ar original 1.6600   0.2500   1.9100 (4.5657)


=>

# Staging環境実行結果(サーバはHeroku, memcachedはアドオン動いている)

            user     system   total   real
memo        0.0099   0.0      0.0099 (0.1472)
cache       0.5000   0.1499   0.6499 (3.6802)
ar original 1.1500   0.1699   1.3200 (3.3467)


考察 chá)

如果使用memoist,相比直接通过ActiveRecord获取缓存,采用低级别缓存的速度明显更快,本地环境快5倍以上,staging环境快2倍以上。

在Staging环境进行测试时,尽管memcached放在另一台服务器上会存在额外的开销,但结果出奇地好(甚至让我对Heroku的速度感到惊讶)。

对于memoist而言,它将数据保存在服务器内存中;而对于低级缓存(Low-Level Caching),则可以将缓存的值委托给memcache,因此从内存使用的角度来看,低级缓存具有优势。

得出结论

根据使用情况,我们决定使用memoist和低级缓存来达到不同的目的。

    • memoist はバッチ処理など一気に大量のデータを処理する場合に用いる

 

    Low-Level Cachingはユーザがよく参照する画面で必要な情報をキャッシュする

参考文献

使用 Ruby 进行基准测试的方法

广告
将在 10 秒后关闭
bannerAds