c - 即使我将输出重定向到/dev/null,printf 仍然会产生成本吗?

标签 c linux performance embedded dev-null

我们有一个包含大量打印消息的守护进程。由于我们正在开发具有弱 CPU 和其他约束硬件的嵌入式设备,因此我们希望在最终版本中最小化 printf 消息的任何类型的成本(IO、CPU 等)。 (用户没有控制台)

我和我的队友意见不合。他认为我们可以将所有内容重定向到/dev/null。它不会花费任何 IO,因此情感将是最小的。但我认为它仍然会消耗 CPU,我们最好为 printf 定义一个宏,这样我们就可以重写“printf”(也许只是返回)。

所以我需要一些关于谁是对的意见。 Linux 会足够聪明以优化 printf 吗?我真的很怀疑。

最佳答案

差不多。

当您将程序的标准输出重定向到 /dev/null 时,对 printf(3) 的任何调用仍将评估所有参数,以及字符串格式化过程仍然会在调用 write(2) 之前发生,它将完整格式化的字符串写入进程的标准输出。在内核级别,数据不会写入磁盘,而是被与特殊设备 /dev/null 关联的处理程序丢弃。

因此,在最好的情况下,您不会绕过或回避评估参数并将它们传递给 printf(printf 背后的字符串格式化作业)的开销,并且至少一个系统调用来实际写入数据,只需将标准输出重定向到 /dev/null。嗯,这在 Linux 上是一个真正的区别。该实现只返回您想要写入的字节数(由调用 write(2) 的第三个参数指定)并忽略其他所有内容(参见 this answer)。根据您正在写入的数据量以及目标设备(磁盘或终端)的速度,性能差异可能会有很大差异。在嵌入式系统上,一般来说,通过重定向到 /dev/null 来切断磁盘写入可以为大量写入数据节省相当多的系统资源。

虽然理论上,该程序可以检测 /dev/null 并在它们遵守的标准(ISO C 和 POSIX)的限制内执行一些优化,基于对常见实现的一般理解,它们实际上不会(即我不知道有任何 Unix 或 Linux 系统这样做)。

POSIX 标准要求对 printf(3) 的任何调用都写入标准输出,因此禁止对 write(2) 的调用不符合标准取决于相关的文件描述符。有关 POSIX 要求的更多详细信息,您可以阅读 Damon's answer .哦,还有一个简短的说明:所有 Linux 发行版实际上都符合 POSIX,尽管没有认证

请注意,如果您完全替换 printf,一些副作用可能会出错,例如 printf("%d%n", a++, &b)。如果您确实需要根据程序执行环境抑制输出,请考虑设置一个全局标志并包装 printf 以在打印前检查该标志 - 它不会使程序减慢到性能损失可见的程度,因为单个条件检查比调用 printf 并执行所有字符串格式化要快很多

关于c - 即使我将输出重定向到/dev/null,printf 仍然会产生成本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54196197/

相关文章:

c - C 中 PriorityQueue 的问题

c - 使用#define 来索引数组?

linux - 无法在本地网络服务器上注册 git runner

c - 如何中断一个进程并稍后继续?

oracle - 如何描述关系数据库中的性能问题?

c - rt linux中如何从用户程序访问内核内存?

python - 快速 'Record Update' 到二进制文件?

database - 数据库如何在更快的磁盘上获得更差的基准测试结果?

javascript - AngularJS:$eval 需要很多时间

c - 为什么我的链接列表只打印最后一个条目?