NullAppender:IAppender is about 20% faster than
NullAppender:AppenderSkeleton on my system when calling log.Debug
several million times inside a tight loop:

public class NullAppender : IAppender
{
 public void Close()
 {
  /* empty */
 }

 public void DoAppend(LoggingEvent loggingEvent)
 {
  /* empty */
 }

 public string Name
 {
  get { return "NullAppender"; }
  set { /* empty */ }
 }
}

public class NullAppender : AppenderSkeleton
{
 protected override void Append(LoggingEvent loggingEvent)
 {
  /* empty */
 }
}

--- Nicko Cadell <[EMAIL PROTECTED]> wrote:

> The AppenderSkeleton uses a lock to ensure that the calls to the
> subclass' Append method are serialised. This makes the job of writing
> a
> custom appender much easier as you don't have to deal with threading.
> 
> The FastDbAppender does not use a lock to serialise the calls to the
> Append method, or to the database. The code in the appender is
> designed
> to be thread safe. This thread safe design allow the appender to work
> without a synchronisation lock, this gives an important performance
> enhancement and is a large part of the 'Fast' in FastDbAppender.
> 
> It may be that the serialisation guarantees of the AppenderSkeleton
> have
> too much of a performance penalty. Perhaps we should have another
> base
> class that provides the same support functions as the
> AppenderSkeleton
> without the synchronisation locking. If we build this new base class
> cleverly we could also use it as a base for the current
> AppenderSkeleton.
> 
> Cheers,
> Nicko
> 
> > -----Original Message-----
> > From: Ron Grabowski [mailto:[EMAIL PROTECTED] 
> > Sent: 16 July 2006 19:40
> > To: [email protected]
> > Subject: AppenderSkeleton.DoAppender calls lock(this) while 
> > some IAppender examples do not
> > 
> > Nicko, AppenderSkeleton's IAppender.DoAppender method 
> > contains this code and comment:
> > 
> >  public void DoAppend(LoggingEvent loggingEvent) 
> >  {          
> > 
> >   // This lock is absolutely critical for correct formatting
> >   // of the message in a multi-threaded environment.  Without
> >   // this, the message may be broken up into elements from
> >   // multiple thread contexts (like get the wrong thread ID).
> >   
> >   lock(this)
> >   {
> >    // [snip]
> >   }
> >  }
> > 
> > FastDbAppender contains this code:
> > 
> >  public virtual void DoAppend(LoggingEvent loggingEvent)  {
> >   using(IDbConnection connection = GetConnection())
> >   {
> >    // Open the connection for each event, this takes advantage
> >    // of the builtin connection pooling
> >    connection.Open();
> >  
> >    using(IDbCommand command = connection.CreateCommand())
> >    {
> >     InitializeCommand(command);
> >  
> >     SetCommandValues(command, loggingEvent);
> >     command.ExecuteNonQuery();
> >    }
> >   }
> >  }
> > 
> > Is it necessary for FastDbAppender to have a lock statement 
> > around that code?
> > 
> > 
> 

Reply via email to