具有可以发送给free()的占位符char *的最有效方法是什么?

bru*_*ais 0 c micro-optimization

我正在开发一个程序,我们在竭尽所能地提高性能,现在我们进入了微优化阶段(同时避免了非严格必要的代码重复)。

想象一下这样的小代码:

propertyContent = gets_x_prop( propStruct );
propertyContent = ( propertyContent ? propertyContent : strdup("") );

/// ....
/// ....
/// ....

free(propertyContent)
Run Code Online (Sandbox Code Playgroud)

做出了决定,我们确定下一个要考虑攻击的是对空字符串strdup的许多调用。
请记住,我们需要有一个char*in变量,以简化随后出现的代码并使之更直接(避免引起的错误(void*)0

问题在于如何优化它……
到目前为止,我们只能实现一个自定义函数:

char* a = malloc(1);
a[0] = NULL;
Run Code Online (Sandbox Code Playgroud)

我们认为,这种方法应该有其他选择。我们还不希望将所有内容替换free()为执行NULL检查的宏,因为我们认为它对我们来说很难。

我们自己的测量表明,当前,等待时间最多的是在malloc中,例如strdup中发生的事件,其中一些会复制空字符串。

Kon*_*lph 7

不需要宏,也不需要空检查。free(NULL)定义明确,安全且禁止操作。

因此,只需删除所有可解决此问题的代码:

propertyContent = gets_x_prop(propStruct);

// …

free(propertyContent);
Run Code Online (Sandbox Code Playgroud)

做完了


也就是说,现在意味着propertyContent可以是NULL,这意味着仍然需要检查它的所有用法NULL,这当然远非理想。将其指向动态分配的空字符串会使它的使用变得更加简单,因此更加安全。您需要确定性能的微小提高是否值得放弃这种安全性。

如果要确保非NULL字符串,但又担心堆碎片,请用可以安全有效地表示空字符串的对象替换对象模型。简单地说,这意味着替换free如下:

// Header

extern const char EMPTY[];
void mystr_free(char *);
Run Code Online (Sandbox Code Playgroud)
// Implementation
const char EMPTY[] = "";

void mystr_free(char *str) {
    if (str != EMPTY) free(str);
}
Run Code Online (Sandbox Code Playgroud)

这与(不必要的)NULL检查宏的方向相同,但是具有永不NULL字符串的所有好处。

  • `str!= EMPTY`-我只担心它可能无法在不同的翻译单元中工作(假设头中有静态const char * EMPTY`并且多个文件都包含它并使用`EMPTY`)。我宁愿在其中一个来源中使用`const char * EMPTY =“”`的标头中的“ extern const char * EMPTY”。 (4认同)
  • @Aconcagua:更好:`const char EMPTY [] =“”;`在许多情况下会更有效。当您可以使地址本身成为链接时间常量时,无需使代码从内存中加载指针值。(在x86-64上,可以在寻址模式下使用完整的静态地址,但不能立即使用。但是在寄存器中创建地址仍然只需要额外的1个RIP相对LEA即可,与`cmp rax,[ Linux非PIE可执行文件可以使用`cmp rax,offset EMPTY`(GAS Intel语法),因为在这种情况下静态地址确实适合32位立即数。) (3认同)
  • 我个人也将保留* pointer *常量:`extern char const * const Empty;`,这将防止用户修改它以指向其他位置。 (2认同)