微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

保持日志记录/调试信息没有运行时损失

如何解决保持日志记录/调试信息没有运行时损失

我有这个 C 代码,它在计算机科学研究的背景下实现了一个算法。提到的代码包含许多 printf 和其他函数调用,它们输出有关算法状态和特定点的关键值的格式化信息。从学习的角度来看,此输出非常有用/清晰。

如果需要,我想以某种方式保留和访问此信息,但如果我不想要这些信息,则不会损害性能

我考虑了一些DEBUG宏定义,并注入了一堆ifdef

#define DEBUG
...
#ifdef DEBUG
    printf("At this point...");
#endif

但这会使代码变得丑陋且难以阅读。

我正在使用 Git,所以也许某种替代版本可能是访问代码的“学习”或“干净”版本的更好方法

所以我的具体问题与实用性和编码约定有关:

  1. 有没有可行的方法来实现这一点?
  2. 这只是一种彻头彻尾的糟糕做法,我不应该让代码做这种事情吗?

解决方法

首先,在您的应用程序不满足实际性能要求之前,性能不是问题。然后您分析您的应用程序,对其进行测量并找到热点。

然后你解决你发现的问题。

如果您有全局调试级别,则可以执行以下操作:

extern volatile atomic unsigned int globalLogLevel;

void logDebugFunc( unsigned int level,const char *function,int line,const char *filename,const char *format,... );

#define LOG_DEBUG( level,format,... ) \
do \
{ \
    if ( level >= globalLogLevel ) \
    { \
        logDebugFunc( level,__func__,__LINE__,\
            __FILE__,__VA_ARGS__ ); \
    } \
} while ( 0 )

(请注意,这会自动捕获函数、文件和行号 - 这样您就可以准确知道每个调试日志条目的来源)

您可以改变日志记录级别,在此示例中,较高的数字表示更详细的日志条目,较低的数字表示更稀有、更重要的日志条目,例如重要事件、错误或警告。

然后就变成了如何在进程运行时更新/更改 globalLogLevel。那里有各种各样的选项 - 您可以使用实时信号来发送新值,或者您可以将 globalLogLevel 重新定义为其他东西 - 一个用于更复杂计算的函数,一个指向 {{1 }}'d 文件,您可以在其中直接更改日志级别。

您可以随心所欲地使这样的事情变得复杂,并且明智地使用不会造成严重的性能损失。 mmap() 语句的命中甚至可能无法衡量,除非您将其嵌入到某个运行频繁的超紧循环中。

更好的是,您不仅不必重新编译进程来启用日志记录,还可以在进程运行时重置日志级别。

您需要这样的东西来弄清楚为什么会从数据中得到间歇性的糟糕结果,但仅限于一个八进制的系统,并且只有在满月时。因为可靠且快速地解决此类问题的唯一方法就是让代码告诉您它所做的一切。

,
/* C file with debug log function */
#ifdef DEBUG
    mysuperdebug_log_function( /* parameters */ )
    {
        /* .... */
    }
#endif


/* .h file */
#ifdef DEBUG
    mysuperdebug_log_function( /* parameters */ );
    #define DEBUGLOG(...)  mysuperdebug_log_function(__VA_ARGS__)
#else
    #define DEBUGLOG(...)
#endif

在您的代码中包含“.h”文件并在您想要输出调试/日志信息时使用宏

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。