Changed all benchmarking reports to be in milliseconds

This commit is contained in:
David Heinemeier Hansson
2008-09-05 14:22:10 +02:00
parent cf0467c642
commit de0e7507de
8 changed files with 60 additions and 32 deletions

View File

@@ -1,5 +1,17 @@
*Edge*
* Changed the X-Runtime header to report in milliseconds [DHH]
* Changed BenchmarkHelper#benchmark to report in milliseconds [DHH]
* Changed logging format to be millisecond based and skip misleading stats [DHH]. Went from:
Completed in 0.10000 (4 reqs/sec) | Rendering: 0.40000 (40%) | DB: 0.04000 (4%) | 200 OK [http://example.com]
...to:
Completed in 100.00ms (View: 400.00, DB: 40.00) | 200 OK [http://example.com]
* Add support for shallow nesting of routes. #838 [S. Brent Faulkner]
Example :

View File

@@ -24,7 +24,7 @@ module ActionController #:nodoc:
if logger && logger.level == log_level
result = nil
seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
logger.add(log_level, "#{title} (#{'%.5f' % seconds})")
logger.add(log_level, "#{title} (#{('%.2f' % (seconds * 1000))}ms)")
result
else
yield
@@ -42,53 +42,65 @@ module ActionController #:nodoc:
protected
def render_with_benchmark(options = nil, extra_options = {}, &block)
unless logger
render_without_benchmark(options, extra_options, &block)
else
db_runtime = ActiveRecord::Base.connection.reset_runtime if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
if logger
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
db_runtime = ActiveRecord::Base.connection.reset_runtime
end
render_output = nil
@rendering_runtime = Benchmark::realtime{ render_output = render_without_benchmark(options, extra_options, &block) }
@view_runtime = Benchmark::realtime { render_output = render_without_benchmark(options, extra_options, &block) }
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
@db_rt_before_render = db_runtime
@db_rt_after_render = ActiveRecord::Base.connection.reset_runtime
@rendering_runtime -= @db_rt_after_render
@view_runtime -= @db_rt_after_render
end
render_output
else
render_without_benchmark(options, extra_options, &block)
end
end
private
def perform_action_with_benchmark
unless logger
perform_action_without_benchmark
else
runtime = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
if logger
seconds = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
logging_view = defined?(@view_runtime)
logging_active_record = Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
log_message = "Completed in #{sprintf("%.2f", seconds * 1000)}ms"
if logging_view || logging_active_record
log_message << " ("
log_message << view_runtime if logging_view
if logging_active_record
log_message << ", " + active_record_runtime + ")"
else
")"
end
end
log_message = "Completed in #{sprintf("%.5f", runtime)} (#{(1 / runtime).floor} reqs/sec)"
log_message << rendering_runtime(runtime) if defined?(@rendering_runtime)
log_message << active_record_runtime(runtime) if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
log_message << " | #{headers["Status"]}"
log_message << " [#{complete_request_uri rescue "unknown"}]"
logger.info(log_message)
response.headers["X-Runtime"] = sprintf("%.5f", runtime)
response.headers["X-Runtime"] = "#{sprintf("%.2f", seconds * 1000)}ms"
else
perform_action_without_benchmark
end
end
def rendering_runtime(runtime)
percentage = @rendering_runtime * 100 / runtime
" | Rendering: %.5f (%d%%)" % [@rendering_runtime, percentage.to_i]
def view_runtime
"View: %.2f" % (@view_runtime * 1000)
end
def active_record_runtime(runtime)
db_runtime = ActiveRecord::Base.connection.reset_runtime
db_runtime += @db_rt_before_render if @db_rt_before_render
db_runtime += @db_rt_after_render if @db_rt_after_render
db_percentage = db_runtime * 100 / runtime
" | DB: %.5f (%d%%)" % [db_runtime, db_percentage.to_i]
def active_record_runtime
db_runtime = ActiveRecord::Base.connection.reset_runtime
db_runtime += @db_rt_before_render if @db_rt_before_render
db_runtime += @db_rt_after_render if @db_rt_after_render
"DB: %.2f" % (db_runtime * 1000)
end
end
end

View File

@@ -15,15 +15,15 @@ module ActionView
# <%= expensive_files_operation %>
# <% end %>
#
# That would add something like "Process data files (0.34523)" to the log,
# That would add something like "Process data files (345.23ms)" to the log,
# which you can then use to compare timings when optimizing your code.
#
# You may give an optional logger level as the second argument
# (:debug, :info, :warn, :error); the default value is :info.
def benchmark(message = "Benchmarking", level = :info)
if controller.logger
real = Benchmark.realtime { yield }
controller.logger.send(level, "#{message} (#{'%.5f' % real})")
seconds = Benchmark.realtime { yield }
controller.logger.send(level, "#{message} (#{'%.2f' % (seconds * 1000)}ms)")
else
yield
end

View File

@@ -1,5 +1,7 @@
*Edge*
* Changed benchmarks to be reported in milliseconds [DHH]
* Connection pooling. #936 [Nick Sieger]
* Merge scoped :joins together instead of overwriting them. May expose scoping bugs in your code! #501 [Andrew White]

View File

@@ -1313,7 +1313,7 @@ module ActiveRecord #:nodoc:
if logger && logger.level <= log_level
result = nil
seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
logger.add(log_level, "#{title} (#{'%.5f' % seconds})")
logger.add(log_level, "#{title} (#{'%.2f' % (seconds * 1000)}ms)")
result
else
yield

View File

@@ -147,10 +147,10 @@ module ActiveRecord
@open_transactions -= 1
end
def log_info(sql, name, runtime)
def log_info(sql, name, seconds)
if @logger && @logger.debug?
name = "#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})"
@logger.debug format_log_entry(name, sql.squeeze(' '))
name = "#{name.nil? ? "SQL" : name} (#{sprintf("%.2f", seconds * 1000)}ms)"
@logger.debug(format_log_entry(name, sql.squeeze(' ')))
end
end

View File

@@ -1,5 +1,7 @@
*Edge*
* Changed cache benchmarking to be reported in milliseconds [DHH]
* Fix Ruby's Time marshaling bug in pre-1.9 versions of Ruby: utc instances are now correctly unmarshaled with a utc zone instead of the system local zone [#900 state:resolved] [Luca Guidi, Geoff Buesing]
* Add Array#in_groups which splits or iterates over the array in specified number of groups. #579. [Adrian Mugnolo] Example:

View File

@@ -62,7 +62,7 @@ module ActiveSupport
write(key, value, options)
@logger_off = false
log("write (will save #{'%.5f' % seconds})", key, nil)
log("write (will save #{'%.2f' % (seconds * 1000)}ms)", key, nil)
value
end