差不多.
当您将程序的stdout重定向到/dev/null
时,对printf(3)
的任何调用仍将计算所有参数,并且字符串格式化过程仍将在调用write(2)
之前进行,后者将完整格式化的字符串写入进程的标准输出.在内核级别,数据不会写入磁盘,而是被与特殊设备/dev/null
相关联的处理程序丢弃.
因此,在最好的情况下,只需将stdout重定向到/dev/null
,就不会绕过或回避计算参数并将其传递到printf
的开销,printf
后面的字符串格式化工作,以及至少一个实际写入数据的系统调用.这在Linux上是一个真正的区别.该实现只返回要写入的字节数(由对write(2)
的调用的第三个参数指定),而忽略其他所有内容(请参见this answer).根据正在写入的数据量和目标设备(磁盘或终端)的速度,性能上的差异可能会有很大的不同.一般来说,在嵌入式系统上,通过重定向到/dev/null
来切断磁盘写入可以为大量写入数据节省相当多的系统资源.
虽然从理论上讲,该程序可以检测/dev/null
个,并在它们遵循的标准(ISO C和POSIX)的限制内执行一些优化,但基于对常见实现的一般理解,它们实际上不能(即我不知道有任何Unix或Linux系统在这样做).
POSIX标准要求对printf(3)
的任何调用写入标准输出,因此根据相关文件描述符 suppress 对write(2)
的调用是不符合标准的.有关POSIX要求的更多详细信息,请阅读Damon's answer.哦,还有一个简短的提示:所有Linux发行版实际上都是POSIX兼容的,尽管不是certified.
请注意,如果完全更换printf
,可能会出现一些副作用,例如printf("%d%n", a++, &b)
.如果您真的需要根据程序执行环境来 suppress 输出,请考虑在打印之前设置全局标志并包装PrtTF来判断标志——它不会在性能损失可见的范围内使程序慢下来,作为一个条件判断,它比调用printf
并进行所有字符串格式化要快much.