Note that there are some explanatory texts on larger screens.

plurals
  1. PORuby: Proxy pattern, reducing method calls
    text
    copied!<p>How do I proxy the ruby logger and keep performance?</p> <p>So, we have an requirement at work, quite reasonable. When a program is sent the signal HUP the log is flushed and restarted. </p> <pre><code>class LocalObject attr_accessor :logger def initialize context # one less method call! Yea! performance++ @logger = context.logger end def something @logger.info "Hello world" end end </code></pre> <p>The problem, is that if context.logger is reset, then @logger still points to the old one.</p> <p>So, I thought I would proxy logger:</p> <pre><code>class LoggerProxy attr_accessor :logger def debug *args @logger.send :debug, args end def info *args @logger.send :info, args end end context.logger = LoggerProxy.new context.logger.logger = Logger.new 'my_file.log' Signal.trap('HUP') { context.logger.logger = Logger.new 'my_file.log' } ... @logger = context.logger @logger.info "Hello world" </code></pre> <p>This works fine, except I've traded one method call for 2 method calls (1 accessor; which returns the logger). I still have to call LoggerProxy.:debug, :info, ..., which in turn calls the original logger! Ergo, 2 methods calls, where there was one.</p> <p>I don't want to monkey with Logger class, or overload it, because I want to use other loggers in the future, syslog, roll my own, or some such.</p> <p>Is there a way reduce the number of method calls for performance?</p> <p>-daniel</p> <p>Update: in response to a question about performance, here is the sample test.</p> <pre><code>require 'logger' require 'benchmark'; class MyLogger attr_accessor :logger def info msg @logger.info msg end end myLogger = Logger.new '/dev/null' # dev null to avoid IO issues myLoggerProxy = MyLogger.new myLoggerProxy.logger = myLogger n = 100000 Benchmark.bm do | benchmarker | # plain logger benchmarker.report { n.times { myLogger.info 'opps' } } # via accessor benchmarker.report { n.times { myLoggerProxy.logger.info 'opps' } } # via proxy benchmarker.report { n.times { myLoggerProxy.info 'opps' } } end user system total real 1.580000 0.150000 1.730000 ( 1.734956) 1.600000 0.150000 1.750000 ( 1.747969) 1.610000 0.160000 1.770000 ( 1.767886) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload