Rails 프로파일링 이야기 또는 Faker가 내 앱에 호주 속어를 가르치려고 시도하는 것을 잡은 방법

8859 단어 rubyrailsprofiling
옛날 옛적에(실제로는 며칠 전) 저는 작은 리팩토링 작업을 수행했습니다. 통합 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

그런 다음 로컬에서 모든 것이 정상인지 확인하고 이상한 점을 발견했습니다.



우와! 우리는 많은 로케일을 가지고 있습니다! 영어 전용 앱에서! 굉장하다!
아니, 그렇지 않아.

나는 이것이 어디에서 왔는지 빠르게 알아냈습니다. 우리 공장에서 사용하는 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를 사용하기 때문에 거의 모든 테스트에서 로케일이 필요합니다.

번들에 이미 test-prof 이 있으므로 부팅 시간 프로파일링은 다음 명령을 실행하는 것만큼 간단했습니다.

$ SAMPLE=1 TEST_STACK_PROF=boot TEST_STACK_PROF_FORMAT=json bundle exec rspec

여기서 무슨 일이 일어났는지 설명하겠습니다.

우리는 Test Prof에게 Stack Profboot mode을 사용하여 테스트 실행을 프로파일링하도록 "말했습니다".

이 모드에서 stackprof는 로드 직후 샘플 수집을 시작하고 첫 번째 테스트 실행 직전에 중지합니다(보다 정확하게는 RSpecbefore(:suite) 후크에서).

또한 SAMPLE=1를 통과하여 하나의 임의 테스트만 실행합니다(이 기능도 provided by Test Prof). 부팅 시간을 프로파일링하기 때문에 특정 예에 대해서는 신경 쓰지 않습니다.

마지막으로 TEST_STACK_PROF_FORMAT는 JSON 형식의 프로파일링 보고서를 생성하는 데 사용됩니다(기능has been added에서 stackprof 자체로, 아직 릴리스되지 않음).

이 JSON 보고서로 무엇을 해야 합니까? Speedscope에 로드하자!

Speedscope은 유명한 프로파일러(stackprof 포함)에서 생성된 JSON 보고서를 시각화하는 Flame 그래프 뷰어입니다.

참고: Flame 그래프란 무엇이며 어떻게 읽을 수 있습니까? “official docs” 및 .

그것이 내가 찾은 것입니다.


기본 Faker 동작(모든 번역 로드)

로케일을 로드하는 데 ~1.1초가 소요되었습니다.

영어 파일만 로드하면(this patch 사용) 어떻게 됩니까?


Patched Faker(영어 번역만 로드 중)

로케일을 로드하는 데 ~0.4초밖에 걸리지 않았습니다.

별거 아닌거같은데 😕

그리고 bootsnap 을 추가하면 "패치"faker 없이 동일한 결과를 얻을 수 있습니다.


부트스냅이 있는 기본 페이커

어쩌면 우리는 많은 메모리를 낭비하고 있습니까?

memory_profiler gem을 사용하여 메모리 사용량을 측정해 보겠습니다.

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.6MB와 7.8MB의 차이는 무시할 수 있습니다. 다시.

우리는 이 특정한 경우에 우리의 프로파일링이 어떤 중요한 문제도 드러내지 않았다는 것을 인정해야 합니다.

그리고 그것은 또한 해피엔딩으로 간주될 수 있습니다 🙂)

추신 Test Prof를 사용한 프로파일링에 대한 다음 게시물도 확인하십시오: "A good doctor for slow Ruby tests""Factory therapy for your Ruby tests" .

추신 네, Faker가 정말 지원합니다Australian Slang .


https://evilmartians.com/chronicles에서 더 많은 개발 기사를 읽어보세요!

좋은 웹페이지 즐겨찾기