- 1 什么是Benchmarking
基准化分析法(benchmarking)就是将本企业各项活动与从事该项活动最佳者进行比较,从而提出行动方法,以弥补自身的不足。benchmarking是将本企业经营的各方面状况和环节与竞争对手或行业内外一流的企业进行对照分析的过程,是一种评价自身企业和研究其他组织的手段,是将外部企业的持久业绩作为自身企业的内部发展目标并将外界的最佳做法移植到本企业的经营环节中去的一种方法。实施benchmarking的公司必须不断对竞争对手或一流企业的产品、服务、经营业绩等进行评价来发现优势和不足。
总的来说,基准化分析法(Benchmarking)就是对企业所有能衡量的东西给出一个参考值,benchmarking可以是一种管理体系、学习过程,它更着重于流程的研究分析。
菲利普·科特勒解释说:“一个普通的公司和世界级的公司相比,在质量、速度和成本绩效上的差距高达10倍之多。benchmarking是寻找在公司执行任务时如何比其他公司更出色的一门艺术。”其实中国古代战略名著孙子兵法也有提到“知己知彼,百战不殆;不知彼而知己,一胜一负;不知彼,不知己,每战必败”。其实这是很简单的道理。
Benchmarking法起源于Xerox公司,施乐曾是影印机的代名词,但日本公司在第二次世界大战以后,勤奋不懈地努力,在诸多方面模仿美国企业的管理、营销等操作方法。日本竞争者介入瓜分市场,从1976年到1982年之间,占有率从80%降至13%。施乐于1979年在美国率先执行benchmarking,总裁柯恩斯1982年赴日学习竞争对手,买进日本的复印机,并通过“逆向工程”,从外向内分析其零部件,并学习日本企业以TQC推动全面品管,从而在复印机上重新获得竞争优势。
而在Rails里面,定义为:times the performance of actions and reports to the logger 就是记录action执行时间,并记录到日志。这个是作为分析Rails方法运行效率的一个重要依据。
- 2 Benchmarking如何运行
- def self.included(base)
- base.extend(ClassMethods)
- base.class_eval do
- alias_method_chain :perform_action, :benchmark
- alias_method_chain :render, :benchmark
- end
- end
- 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? # 1 render开始前 的数据库时间
- render_output = nil
- @rendering_runtime = Benchmark::realtime{ render_output = render_without_benchmark(options, extra_options, &block) } #计算执行rendering总共所需要的总时间
- if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
- @db_rt_before_render = db_runtime
- @db_rt_after_render = ActiveRecord::Base.connection.reset_runtime # 2 render结束后数据库运行时间
- @rendering_runtime -= @db_rt_after_render #render时间就是总时间减去数据库执行时间
- end
- render_output
- end
- end
- def perform_action_with_benchmark
- unless logger
- perform_action_without_benchmark
- else
- runtime = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max #先执行perform_action方法,至少假定为0.0001秒
- 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)
- end
- end
- def rendering_runtime(runtime)
- percentage = @rendering_runtime * 100 / runtime
- " | Rendering: %.5f (%d%%)" % [@rendering_runtime, percentage.to_i]
- end
- def active_record_runtime(runtime)
- db_runtime = ActiveRecord::Base.connection.reset_runtime # 3 其他的数据库时间 就是在send(controller_action_name)方法中执行的数据库操作
- db_runtime += @db_rt_before_render if @db_rt_before_render # 加上 前面1 提到的
- db_runtime += @db_rt_after_render if @db_rt_after_render # 加上 前面2 提到的
- db_percentage = db_runtime * 100 / runtime
- " | DB: %.5f (%d%%)" % [db_runtime, db_percentage.to_i]
- end