AppProfiler를 사용하여 Mongoid 문제 성능 프로파일링

MONGOID-4889에서는 포함할 문서 목록의 크기가 커짐에 따라 많은 수의 포함된 문서를 모델 인스턴스에 할당하는 데 시간이 더 오래 걸린다고 주장했습니다. 이는 이 프로세스 중에 수행되는 데이터베이스 작업이 없다는 점에서 주목할 만하며, 이는 라이브러리 자체에 잠재적인 문제가 있음을 나타냅니다. 티켓 작성자는 Mongoid::Association::Embedded::EmbedsMany::Proxy#object_already_related? 을 이 성능 문제의 가능한 원인으로 식별했지만 이를 검증하는 최선의 방법을 알고 싶었습니다.

Ruby 프로파일링에 대해 연구하는 동안 "How to Fix Slow Code in Ruby"에서 Shopify의 블로그 게시물을 발견했습니다. 전체 게시물이 매우 통찰력이 있었지만 Shopify의 app_profiler 라이브러리로 연결되었습니다. 이 라이브러리는 코드를 자동으로 프로파일링하고 출력을 speedscope의 로컬 인스턴스로 리디렉션하는 데 사용할 수 있습니다. 이전에 Flame Graphs을 사용하여 수집된 CPU 스택 추적 중 perf 으로 작업했습니다.

Jira 티켓의 샘플 코드를 수정하면 다음과 같은 결과가 나타납니다.

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'

  gem 'mongoid'
  gem 'app_profiler'
end

class Foo
  include Mongoid::Document
  embeds_many :bars
end

class Bar
  include Mongoid::Document
  embedded_in :foo
end

# AppProfiler forms the output filename using Time.zone.now
require 'active_support/core_ext/time/zones'
Time.zone = 'Pacific Time (US & Canada)'
AppProfiler.root = Pathname.new(__dir__)
AppProfiler.profile_root = Pathname.new(__dir__)

arr = Array.new(2000) { Bar.new }
report = AppProfiler.run(mode: :cpu) do
  Foo.new.bars = arr
end
report.view


위의 코드를 실행하면 MongoDB 연결 문자열이나 활성 클러스터가 필요하지 않지만 Bar의 새 인스턴스 2000개를 새로 생성된 Foo 인스턴스에 포함하려고 시도합니다. 완료되면 object_already_related?에 대한 호출이 추가 조사 대상이 될 수 있다는 초기 의심을 강화하는 다음 차트가 생성됩니다.



AppProfiler는 Rails 애플리케이션에 삽입되도록 설계되었지만 위에서 볼 수 있듯이 독립 실행형 Ruby 스크립트에서도 작동하도록 쉽게 조정할 수 있습니다.

좋은 웹페이지 즐겨찾기