首页 > 解决方案 > 将占位符 char* 发送到 free() 的最有效方法是什么?

问题描述

我正在开发一个程序,我们正在挤压我们可以获得的每一点性能,我们现在进入微优化阶段(同时避免非严格必要的代码重复)。

想象一下这样的小代码:

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

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

free(propertyContent)

做出了决定,我们确信下一个要考虑攻击的是对空字符串的 strdup 的许多调用。
请记住,我们需要char*在该变量中添加一个来简化后面的代码并使其更直接(避免使用 的错误(void*)0

问题在于如何优化它......
到目前为止,我们只能达到一个自定义功能:

char* a = malloc(1);
a[0] = NULL;

我们认为应该有一些替代这种方法的方法。我们还不想free()用执行 NULL 检查的宏替换所有内容,因为我们认为它对我们来说更难解决。

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

标签: cmicro-optimization

解决方案


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

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

propertyContent = gets_x_prop(propStruct);

// …

free(propertyContent);

完毕。


也就是说,这现在意味着propertyContentcan be NULL,这意味着它的所有用法仍然需要检查NULL,这当然远非理想。让它指向一个动态分配的空字符串使它的使用更简单,因此更安全。您需要决定性能的微小提升是否值得放弃这种安全性。

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

// Header

extern const char EMPTY[];
void mystr_free(char *);
// Implementation
const char EMPTY[] = "";

void mystr_free(char *str) {
    if (str != EMPTY) free(str);
}

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


推荐阅读