2
bool kDebuggingEnabled = NO;
...
for(i=0; i<length; i++){
 ...
 if (kDebuggingEnabled) {
  NSLog (@"Value of variable # %i",$resultingOptions);
 }
}

每当我的应用程序上线时,我的代码每次都会检查有关 NSLog 的条件。有没有更好的方法来提高我的代码性能?

4

3 回答 3

5

您可以使用预处理器宏来打开和关闭登录。一个很好的例子是DLog来自 Marcus Zarra 在Cocoa is My Girlfriend博客上的宏。

#ifdef DEBUG
    #define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
    #define DLog(...) do { } while (0)
#endif

您可以将上述内容放在您的 prefix.pch 文件中,然后简单地将NSLog语句替换为DLog语句。您还需要确保DEBUG在调试构建配置中进行了设置。

像这样使用预处理器宏意味着日志代码不会被编译到您的发布版本中,因此不会对日志语句造成性能影响。

该博客文章还包含一些其他有用的宏来处理断言。

于 2012-08-24T04:37:15.453 回答
2

您有 3 个选择:

1) 如果您想在构建时启用/禁用日志。预处理器解决方案是最好的:

// define MY_ENABLE_LOGS in your build settings for the debug configuration only, for example
#ifdef MY_ENABLE_LOGS
#define MYLog(...) NSLog(__VA_ARGS__)
#else
#define MyLog(...) do { } while(0)
#endif

2) 如果您希望能够在运行时启用/禁用日志(例如,基于一些隐藏的偏好),您的解决方案可能是最好的。不过,您可以尝试提示编译器进行一些优化:

// tell the compiler it's unlikely that kDebuggingEnabled will be true
#define MYLog(...) do { if (__builtin_expect(kDebuggingEnabled, 0)) { NSLog(__VA_ARGS__); } } while(0)

3) 最后一个选项稍微复杂一些,但可以提供比日志更丰富的信息,并且仅取决于您希望提供的日志记录类型。这个想法是使用带有 dtrace 的自定义探针(也可以在 Instruments 中使用)。这仅适用于 OS X(不适用于 iOS)。例如,参见http://www.macresearch.org/tuning-cocoa-applications-using-dtrace-custom-static-probes-and-instruments 。

请注意,您可以根据需要混合 1) 和 2)。3) 意味着在不跟踪探测时几乎为零成本,并且可以提供比简单的日志字符串更丰富的信息。

这些解决方案的一个警告:当未定义 MY_ENABLE_LOGS 时,不会评估日志的参数,这可能会改变您的应用程序行为。

于 2012-08-24T05:25:31.707 回答
1

使用预处理器宏检查您是否正在构建调试:

#if DEBUG
// do stuff
#end

如果预处理器(在编译器之前运行的东西)评估 DEBUG 为真,它将保留代码供编译器编译,但如果 DEBUG 不存在或为假,它将删除那段代码。

于 2012-08-24T04:31:18.140 回答