Rails에서 사용되는 메소드를 자동으로 벤치마킹하는 gem을 만들어 본 이야기
배경
거대화 노후화해 온 Rails 서비스의 퍼포먼스 개선 작업을 할 때, 간편하게 각종 메소드의 벤치마크를 취하면서 트라이앤드 에러를 진행하고 싶었다.
처음에는 어리석게 benchmark 라이브러리을 사용하여 메소드의 벤치 마크를 측정하려고했습니다. (덧붙여서 프로파일러는 stackprof 등을 사용)
sample_controller.rbclass OldCarsController < ApplicationController
def index
Benchmark.bm 10 do |r| # なんか無茶なやり方
r.report "index action" do
@q = OldCar.ransack(params[:q])
time_consuming_method1
time_consuming_method2
@old_cars = @q.result(distinct: true)
end
end
end
private
def time_consuming_method1
sleep(1)
end
def time_consuming_method2
100000.times { OldCar.new }
end
end
예를 들어 이런 식으로 index 액션을 실행하면, 다음과 같은 로그가 나오고 index 액션의 벤치마크를 취할 수 있지만, 복수의 메소드나 액션의 벤치마크를 취하려고 하면 그때마다 기술을 추기하지 않으면 갈 수 없어 가 귀찮고 로그도 일단 로그 파일에 두고 싶다.
sample.log user system total real
index action 2.757912 0.000000 2.757912 ( 3.773948)
또, 계측하고 싶은 처리 내용을 Benchmark.bm do ~ end
로 둘러싸면, 그 처리 부분의 반환값은 벤치마크 오브젝트가 되므로, 반환값을 다른 메소드로 사용하는 것과 같은 메소드라고 이 계측 방법은 사용하기 어렵다.
sample_controller.rbclass OldCarsController < ApplicationController
def index
Benchmark.bm 10 do |r|
r.report "index action" do
@q = OldCar.ransack(params[:q])
time_consuming_method1
time_consuming_method2
@old_cars = @q.result(distinct: true)
end
end
# 戻り値が@old_carsの値ではなく計測結果のオブジェクトになる
# => [#<Benchmark::Tms:0x000055d3ab7be4c0 @label="index action", @real=3.773947899997438, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=2.7579119999999993, @total=2.7579119999999993>]
end
# (省略)
end
라고 하는 것으로 공부가 되면 이런 문제를 해소할 수 있을 것 같은 gem을 만들어 보았다.
htps : // 기주 b. 코 m / 잠시 / R ben ch r r
시연
config/environments/development.rbrequire "active_support/core_ext/integer/time"
Rails.application.configure do
config.eager_load = true # 設定をtrueに変更
config.after_initialize do # 設定を追加
Rbenchmarker.setup switch: 'on', output_log_path: nil, except_classes: [], except_modules: []
end
# (省略)
end
sample_controller.rbclass OldCarsController < ApplicationController
rbenchmarker all: __FILE__ # 記述を追加
def index
# (省略)
end
이런 식으로 준비하고 index 액션을 두드리면
log/rbenchmark.log# Logfile created on 2021-02-11 17:18:16 +0000 by logger.rb/v1.4.2
I, [2021-02-11T17:18:16.305563 #1] INFO -- : == Start recording Rbenchmarker ==
I, [2021-02-11T17:18:43.097913 #1] INFO -- :
report def time_consuming_method1 instance method: current time
user: 0.00265500, system: 0.00019400, total: 0.00284900, real: 1.00423010
report def time_consuming_method1 instance method: total time for 1 times called
user: 0.00265500, system: 0.00019400, total: 0.00284900, real: 1.00423010
report def time_consuming_method1 instance method: avarage time
user: 0.00265500, system: 0.00019400, total: 0.00284900, real: 1.00423010
I, [2021-02-11T17:18:45.519836 #1] INFO -- :
report def time_consuming_method2 instance method: current time
user: 2.40189500, system: 0.00000000, total: 2.40189500, real: 2.41995030
report def time_consuming_method2 instance method: total time for 1 times called
user: 2.40189500, system: 0.00000000, total: 2.40189500, real: 2.41995030
report def time_consuming_method2 instance method: avarage time
user: 2.40189500, system: 0.00000000, total: 2.40189500, real: 2.41995030
I, [2021-02-11T17:18:45.521387 #1] INFO -- :
report def index instance method: current time
user: 2.40906800, system: 0.00026500, total: 2.40933300, real: 3.43638710
report def index instance method: total time for 1 times called
user: 2.40906800, system: 0.00026500, total: 2.40933300, real: 3.43638710
report def index instance method: avarage time
user: 2.40906800, system: 0.00026500, total: 2.40933300, real: 3.43638710
통상대로의 반환값을 돌려주면서, 뒤에서 이런 느낌의 로그가 출력되게 되었다.
( current time
가 메서드가 실행되었을 때의 시간
우선의 타임은 간편하게 측정할 수 있게 되어, 공부도 되었으므로 좋다고 한다.
실패담
제작을 시작한 시점에서는 (조사 부족으로) 눈치채지 못했지만, 비슷한 발상의 gem은 이미 있었다.
htps : // 기주 b. 코 m / 이코
기능면에서 몇 가지 다른 점도 있어 자신이 하고 싶은 것은 자신의 젬이 실현했지만, 바퀴의 재발명감은 부정할 수 없었다.
Reference
이 문제에 관하여(Rails에서 사용되는 메소드를 자동으로 벤치마킹하는 gem을 만들어 본 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/shibadai/items/1e171b10eb271de42a9c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
class OldCarsController < ApplicationController
def index
Benchmark.bm 10 do |r| # なんか無茶なやり方
r.report "index action" do
@q = OldCar.ransack(params[:q])
time_consuming_method1
time_consuming_method2
@old_cars = @q.result(distinct: true)
end
end
end
private
def time_consuming_method1
sleep(1)
end
def time_consuming_method2
100000.times { OldCar.new }
end
end
user system total real
index action 2.757912 0.000000 2.757912 ( 3.773948)
class OldCarsController < ApplicationController
def index
Benchmark.bm 10 do |r|
r.report "index action" do
@q = OldCar.ransack(params[:q])
time_consuming_method1
time_consuming_method2
@old_cars = @q.result(distinct: true)
end
end
# 戻り値が@old_carsの値ではなく計測結果のオブジェクトになる
# => [#<Benchmark::Tms:0x000055d3ab7be4c0 @label="index action", @real=3.773947899997438, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=2.7579119999999993, @total=2.7579119999999993>]
end
# (省略)
end
config/environments/development.rb
require "active_support/core_ext/integer/time"
Rails.application.configure do
config.eager_load = true # 設定をtrueに変更
config.after_initialize do # 設定を追加
Rbenchmarker.setup switch: 'on', output_log_path: nil, except_classes: [], except_modules: []
end
# (省略)
end
sample_controller.rb
class OldCarsController < ApplicationController
rbenchmarker all: __FILE__ # 記述を追加
def index
# (省略)
end
이런 식으로 준비하고 index 액션을 두드리면
log/rbenchmark.log
# Logfile created on 2021-02-11 17:18:16 +0000 by logger.rb/v1.4.2
I, [2021-02-11T17:18:16.305563 #1] INFO -- : == Start recording Rbenchmarker ==
I, [2021-02-11T17:18:43.097913 #1] INFO -- :
report def time_consuming_method1 instance method: current time
user: 0.00265500, system: 0.00019400, total: 0.00284900, real: 1.00423010
report def time_consuming_method1 instance method: total time for 1 times called
user: 0.00265500, system: 0.00019400, total: 0.00284900, real: 1.00423010
report def time_consuming_method1 instance method: avarage time
user: 0.00265500, system: 0.00019400, total: 0.00284900, real: 1.00423010
I, [2021-02-11T17:18:45.519836 #1] INFO -- :
report def time_consuming_method2 instance method: current time
user: 2.40189500, system: 0.00000000, total: 2.40189500, real: 2.41995030
report def time_consuming_method2 instance method: total time for 1 times called
user: 2.40189500, system: 0.00000000, total: 2.40189500, real: 2.41995030
report def time_consuming_method2 instance method: avarage time
user: 2.40189500, system: 0.00000000, total: 2.40189500, real: 2.41995030
I, [2021-02-11T17:18:45.521387 #1] INFO -- :
report def index instance method: current time
user: 2.40906800, system: 0.00026500, total: 2.40933300, real: 3.43638710
report def index instance method: total time for 1 times called
user: 2.40906800, system: 0.00026500, total: 2.40933300, real: 3.43638710
report def index instance method: avarage time
user: 2.40906800, system: 0.00026500, total: 2.40933300, real: 3.43638710
통상대로의 반환값을 돌려주면서, 뒤에서 이런 느낌의 로그가 출력되게 되었다.
(
current time
가 메서드가 실행되었을 때의 시간우선의 타임은 간편하게 측정할 수 있게 되어, 공부도 되었으므로 좋다고 한다.
실패담
제작을 시작한 시점에서는 (조사 부족으로) 눈치채지 못했지만, 비슷한 발상의 gem은 이미 있었다.
htps : // 기주 b. 코 m / 이코
기능면에서 몇 가지 다른 점도 있어 자신이 하고 싶은 것은 자신의 젬이 실현했지만, 바퀴의 재발명감은 부정할 수 없었다.
Reference
이 문제에 관하여(Rails에서 사용되는 메소드를 자동으로 벤치마킹하는 gem을 만들어 본 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/shibadai/items/1e171b10eb271de42a9c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Rails에서 사용되는 메소드를 자동으로 벤치마킹하는 gem을 만들어 본 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/shibadai/items/1e171b10eb271de42a9c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)