保留 logging/debugging 信息而不会造成运行时损失
Keeping logging/debugging info without runtime penalty
我有这段 C 代码,它在计算机科学研究的背景下实现了一种算法。提到的代码包含许多 printf
和其他函数调用,这些函数调用输出有关算法状态和特定点关键值的格式化信息。从学习的角度来看,这个输出非常useful/clear。
如果需要,我想以某种方式保存和访问此信息,但如果我不需要此类信息,则不会影响性能。
想了一些DEBUG
宏定义,注入了一堆ifdef
:
#define DEBUG
...
#ifdef DEBUG
printf("At this point...");
#endif
但这会使代码难看且难以阅读。
我正在使用 Git,因此也许某种替代版本是访问代码的“学习”或“干净”版本的更好方法。
所以我的具体问题与实用性和编码约定有关:
- 有没有实用的方法可以做到这一点?
- 这是否只是一种彻头彻尾的错误做法,我不应该让代码做这种事情吗?
/* 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”文件并在您想要输出 debug/log 信息时使用宏
首先,在您的应用程序不满足实际性能要求之前,性能不是问题。然后分析您的应用程序、对其进行测量并找到热点。
然后你解决你发现的问题。
如果你有全局调试级别,你可以这样做:
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__, format, __VA_ARGS__ ); \
} \
} while ( 0 )
(请注意,这会自动捕获函数、文件和行号 - 这样您就可以确切地知道每个调试日志条目的来源)
您可以改变日志记录级别,在此示例中,较高的数字表示更详细的日志条目,较低的数字表示更罕见、更重要的日志条目,例如重要事件、错误或警告。
那么就变成了如何update/change在globalLogLevel
的过程中运行。那里有各种各样的选项——你可以使用实时信号发送一个新值,或者你可以将 globalLogLevel
重新定义为其他东西——一个用于更复杂计算的函数,一个指向 [=13] 的指针=]' 文件,您可以在其中直接更改日志级别。
您可以根据需要将类似的东西做得尽可能复杂,如果使用得当,性能损失不会太大。 if
语句的命中率甚至可能无法衡量,除非您将它嵌入到运行很多的超紧密循环中。
更好的是,您不仅不必重新编译您的进程来启用日志记录,您还可以在进程处于 运行.
时重置日志级别
你需要这样的东西来弄清楚为什么你从数据中得到间歇性的坏结果,但只在一个八人系统上,而且只在满月的时候。因为可靠且快速地解决此类问题的唯一方法就是让代码告诉您它所做的一切。
我有这段 C 代码,它在计算机科学研究的背景下实现了一种算法。提到的代码包含许多 printf
和其他函数调用,这些函数调用输出有关算法状态和特定点关键值的格式化信息。从学习的角度来看,这个输出非常useful/clear。
如果需要,我想以某种方式保存和访问此信息,但如果我不需要此类信息,则不会影响性能。
想了一些DEBUG
宏定义,注入了一堆ifdef
:
#define DEBUG
...
#ifdef DEBUG
printf("At this point...");
#endif
但这会使代码难看且难以阅读。
我正在使用 Git,因此也许某种替代版本是访问代码的“学习”或“干净”版本的更好方法。
所以我的具体问题与实用性和编码约定有关:
- 有没有实用的方法可以做到这一点?
- 这是否只是一种彻头彻尾的错误做法,我不应该让代码做这种事情吗?
/* 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”文件并在您想要输出 debug/log 信息时使用宏
首先,在您的应用程序不满足实际性能要求之前,性能不是问题。然后分析您的应用程序、对其进行测量并找到热点。
然后你解决你发现的问题。
如果你有全局调试级别,你可以这样做:
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__, format, __VA_ARGS__ ); \
} \
} while ( 0 )
(请注意,这会自动捕获函数、文件和行号 - 这样您就可以确切地知道每个调试日志条目的来源)
您可以改变日志记录级别,在此示例中,较高的数字表示更详细的日志条目,较低的数字表示更罕见、更重要的日志条目,例如重要事件、错误或警告。
那么就变成了如何update/change在globalLogLevel
的过程中运行。那里有各种各样的选项——你可以使用实时信号发送一个新值,或者你可以将 globalLogLevel
重新定义为其他东西——一个用于更复杂计算的函数,一个指向 [=13] 的指针=]' 文件,您可以在其中直接更改日志级别。
您可以根据需要将类似的东西做得尽可能复杂,如果使用得当,性能损失不会太大。 if
语句的命中率甚至可能无法衡量,除非您将它嵌入到运行很多的超紧密循环中。
更好的是,您不仅不必重新编译您的进程来启用日志记录,您还可以在进程处于 运行.
时重置日志级别你需要这样的东西来弄清楚为什么你从数据中得到间歇性的坏结果,但只在一个八人系统上,而且只在满月的时候。因为可靠且快速地解决此类问题的唯一方法就是让代码告诉您它所做的一切。