レールプロファイリング物語、またはどのように私は私のアプリオーストラリアの俗語を教えるしようとしてfakerキャッチ


一度(実際には、数日前)私は小さなリファクタリングタスクに取り組んできた factory_bot メーラープレビューに.
かなり単純なタスクのように見えた:ロードfactory_bot_rails 構文法を含める
# spec/mailers/previews/application_preview.rb

require "factory_bot_rails"

class ApplicationPreview < ActionMailer::Preview
  include FactoryBot::Syntax::Methods

  private

  # user record for previews
  def user
    @user ||= build_stubbed :user
  end
end
その後、私はすべてがローカルでokであるとチェックしました、そして、何か奇妙なものを見つけました:

すごい!私たちはたくさんのロケールを持っている!私たちの英語のみアプリ!それは素晴らしいです!
いいえ.
私はすぐにどこから来たかを見つけた faker 我々は工場で使用する宝石.
チェックしたthe repo 少し驚いた.
require 'i18n'

#...

I18n.load_path += Dir[File.join(mydir, 'locales', '**/*.yml')]
I18n.reload! if I18n.backend.initialized?
Fakerはすべてのロケールファイルを読み込み、必要な唯一のロケールを選択できません.それは私にとって予期しない振舞いだった.
注:アプリケーションで使用するロケールを設定することで明示的に指定できます config.i18n.available_locales ; 設定されていない場合は、ロードされたすべてのロケールが利用可能になります.
私は、不必要なYMLファイルの束のロードがアプリケーション起動時間に影響する方法をチェックすることに決めました.
以来i18n 不安定なロケールをロードします、私は私のものに以下の線を加えましたrspec_helper.rb これを強制的に行うには:
# add to rails_helper.rb
I18n.backend.load_translations
注:使用するのでfaker 工場では、ほぼすべてのテストでlocalesが必要です.
私はもう test-prof 私のバンドルでは、ブート時のプロファイリングはこのコマンドを実行するのと同じくらい簡単でした.
$ SAMPLE=1 TEST_STACK_PROF=boot TEST_STACK_PROF_FORMAT=json bundle exec rspec
ここで何が起こったのか説明しましょう.
私たちは“テスト”のprofをテストするためのテストを使用してプロファイルを教えてStack Prof and boot mode .
そのモードではstackprof ロード直後にサンプルを収集し、最初のテストを実行する前に停止しますbefore(:suite) フック).
我々もSAMPLE=1 つだけのランダムなテストを実行するprovided by Test Prof ): ブート時のプロファイルをしているので、特定の例については気にしません.
最後にTEST_STACK_PROF_FORMAT はJSON形式でプロファイルレポートを生成するために使用されますhas been added to stackprof が、まだリリースされていない).
このJSONレポートでどうするか?ロードしましょうSpeedscope !
Speedscope 人気のプロファイラによって生成されたJSONレポートを可視化する炎グラフビューアーですstackprof ).
注:炎グラフとはどのようにそれらを読むか?チェックアウト“official docs” また、
それは私が見つけたものです.

デフォルトのfakerの動作(すべての翻訳を読み込み)
私たちは〜1 sローディングロケールを過ごした.
私たちが英語のファイルだけをロードするならばthis patch )?

パッチをつけられたfaker(英語の翻訳だけをロードする)
ロケールをロードするには- 0.4 sしかかかりませんでした.
それは大きな取引ではないように見える😕
そして、我々が加えるならば bootsnap 「パッチをかけることなし」と同じ結果を達成できましたfaker :

デフォルトのfaker
多分、我々はたくさんの記憶を浪費します?
メモリフットプリントを測定してみましょう memory_profiler ジェム
require "memory_profiler"

MemoryProfiler.report do
  I18n.backend.load_translations
end.yield_self(&:pretty_print)
すべての利用可能なロケールをロードするとき:
retained objects by gem
-----------------------------------
    147586  psych
      5462  i18n-1.5.3
         2  activesupport-6.0.0.beta1

retained objects by class
-----------------------------------
    148628  String
      2550  Array
      1022  Symbol
       848  Hash
         2  Proc
英語版のみ
retained objects by gem
-----------------------------------
     44301  psych
      3418  i18n-1.5.3
         2  activesupport-6.0.0.beta1

retained objects by class
-----------------------------------
     45240  String
      1202  Array
       910  Symbol
       367  Hash
         2  Proc
したがって、2.6 MB対7.8 MB -違いは無視できます.再び.
この特定のケースでは、我々のプロファイリングがどんな重要な問題も明らかにしなかったと認めなければなりません.
そして、それもハッピーエンドと考えられる🙂)
P . S .を使用してプロファイリングに関するこれらの記事もチェックしてください."A good doctor for slow Ruby tests" and "Factory therapy for your Ruby tests" .
P . P . S .はい、faker本当にサポートAustralian Slang .
記事を読むhttps://evilmartians.com/chronicles !