代码之家  ›  专栏  ›  技术社区  ›  Charles

C日志记录的性能技巧

  •  5
  • Charles  · 技术社区  · 15 年前

    我正在研究C日志,如果消息低于日志阈值,我不希望日志消息花费任何时间处理。我能看到的最好的log4net是在评估日志参数后进行阈值检查。

    例子:

    _logger.Debug( "My complicated log message " + thisFunctionTakesALongTime() + " will take a long time" )
    

    即使阈值高于调试,此函数takeSalongtime仍将被评估。

    在log4net中,你应该使用logger.isdebugenabled,这样你就可以

    if( _logger.isDebugEnabled )
        _logger.Debug( "Much faster" )
    

    我想知道对于.NET日志记录,是否有更好的解决方案,在每次我想要日志记录时都不需要检查。

    在C++中,我被允许做。

    LOG_DEBUG( "My complicated log message " + thisFunctionTakesALongTime() + " will take no time" )
    

    因为我的日志调试宏本身会检查日志级别。这使我可以在整个应用程序中自由地使用一行日志消息,这是我非常喜欢的。有人知道用C语言复制这种行为的方法吗?

    4 回复  |  直到 15 年前
        1
  •  8
  •   Jeff Meatball Yang    15 年前

    如果您可以以.NET 3.5(c 3.0)为目标,则可以使用 extension methods 包装 if 声明。

    因此,您可以执行等效的“宏”:

    logger.Log_Debug("Much faster");
    
    logger.Log_Debug(() => { "My complicated log message " + thisFunctionTakesALongTime() + " will take no time" });
    

    通过在此方法中包装签入:

    public class Log4NetExtensionMethods {
        // simple string wrapper
        public void Log_Debug(this log4net.ILog logger, string logMessage) {
            if(logger.isDebugEnabled) {
                 logger.Debug(logMessage);
            }
        }
    
        // this takes a delegate so you can delay execution
        // of a function call until you've determined it's necessary
        public void Log_Debug(this log4net.ILog logger, Func<string> logMessageDelegate) {
            if(logger.isDebugEnabled) {
                 logger.Debug(logMessageDelegate());
            }
        }
    }
    
        2
  •  2
  •   blammo    15 年前

    17.4.2条件属性

    Conditional属性启用条件方法的定义。条件属性通过测试条件编译符号来指示条件。根据是否在调用点定义了此符号,对条件方法的调用将被包括或忽略。如果定义了符号,则包含调用;否则,省略调用(包括调用参数的计算)。

    [ Conditional("DEBUG") ]
    public static void LogLine(string msg,string detail)
    {
        Console.WriteLine("Log: {0} = {1}",msg,detail);
    }
    
    public static void Main(string[] args)
    {
        int Total = 0;
        for(int Lp = 1; Lp < 10; Lp++)
        {
            LogLine("Total",Total.ToString());
            Total = Total + Lp;
        }
    }
    
        3
  •  1
  •   bobbymcr    15 年前

    这里的问题是,在调用方法之前必须计算所有方法参数。考虑到您使用的语法,没有办法解决这个问题。因为C没有真正的预处理器或宏,所以不能执行“日志调试”之类的操作。你能做的最好的就是使用 if (logger.isDebugEnable) 如建议。

    我唯一能想到的就是使用lambda表达式之类的东西来延迟计算。但我会警告你 最终肯定会有更多的性能冲击。 .

    internal class Sample
    {
        private static void Main(string[] args)
        {
            DelayedEvaluationLogger.Debug(logger, () => "This is " + Expensive() + " to log.");
        }
    
        private static string Expensive()
        {
            // ...
        }
    }
    
    internal static class DelayedEvaluationLogger
    {
        public static void Debug(ILog logger, Func<string> logString)
        {
            if (logger.isDebugEnabled)
            {
                logger.Debug(logString());
            }
        }
    }
    
        4
  •  -1
  •   blammo    15 年前

    没有预处理器,你就是索尔。当然,在将代码提供给C编译器之前,没有什么能阻止您使用它。