【问题标题】:Performance of GNU C implementation of getcwd()getcwd() 的 GNU C 实现的性能
【发布时间】:2014-07-25 13:28:12
【问题描述】:

根据 the GNU Lib C documentation on getcwd()...

此函数的 GNU C 库版本还允许您为缓冲区参数指定空指针。然后 getcwd 自动分配一个缓冲区,与 malloc 一样(请参阅无约束分配)。如果大小大于零,那么缓冲区就是那么大;否则,缓冲区将与保存结果所需的一样大。

我现在提请您注意使用 GNU 文档中描述的标准 getcwd() 的实现:

char* gnu_getcwd ()
{
   size_t size = 100;
   while (1)
   {
      char *buffer = (char *) xmalloc (size);
      if (getcwd (buffer, size) == buffer)
        return buffer;
      free (buffer);
      if (errno != ERANGE)
        return 0;
      size *= 2;
   }
}

这对于可移植性和稳定性来说似乎很好,但它也看起来像是对所有分配和释放内存的笨拙妥协。鉴于可能会频繁调用该函数,这是否可能是性能问题?

*说“配置它”很容易,但这不能解释所有可能的系统;现在或未来。

【问题讨论】:

  • Linux 上getpwd 的实际glibc 实现实际上并没有使用手册中描述的实现。相反,它分配一个缓冲区,该缓冲区是相应 Linux 系统调用支持的最大可能路径名。如果失败,则 glibc 实现将退回到通过.. 目录条目向上目录树向上的传统方法。

标签: c performance getcwd


【解决方案1】:

初始大小为 100,包含 99 个字符的路径,比典型系统上存在的大多数路径都长。这意味着一般没有“分配和释放内存”,浪费的字节不超过 98 个。

每次尝试加倍的启发式方法意味着最多会发生对数个虚假分配。在许多系统上,路径的最大长度是有限的,这意味着导致的重新分配的数量是有限的。

只要将getcwd 用作黑匣子,这几乎是最好的。

【讨论】:

    【解决方案2】:

    这不是性能问题,因为它是 getcwd 函数。如果该功能在您的关键路径中,那么您做错了。

    除了开玩笑,没有可以删除的代码。您可以通过分析改进这一点的唯一方法是调整幻数“100”(这是速度/空间的权衡)。即使那样,您也只能针对 您的 文件系统对其进行优化。

    您可能还考虑将 free/malloc 替换为 realloc,但这会导致不必要的内存复制,并且错误检查甚至不会减少代码。

    【讨论】:

      【解决方案3】:

      感谢大家的意见。我最近总结了从一开始就应该显而易见的事情:根据目标平台定义值(在本例中为“100”)和要使用的增量公式(在本例中为 x2)。这可能适用于所有系统,尤其是在使用附加标志的情况下。

      【讨论】:

        猜你喜欢
        • 2021-10-03
        • 1970-01-01
        • 1970-01-01
        • 2011-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        相关资源
        最近更新 更多