60
задан 16 January 2019 в 16:55

5 ответов

В значительной степени.

при перенаправлении stdout программы к /dev/null любой вызов к printf(3) все еще оценит все аргументы, и строковый процесс форматирования все еще произойдет прежде, чем звонить write(2), который пишет полную отформатированную строку в стандартный вывод процесса. Именно на уровне ядра данные не записаны в диск, но отброшены обработчиком, связанным со специальным устройством /dev/null.

Так в самом лучшем, Вы не обойдете или уклонитесь от издержек оценки аргументов и передачи их к printf, строковое задание форматирования позади printf, и по крайней мере один системный вызов для фактической записи данных, только путем перенаправления stdout к /dev/null. Ну, это - истинное различие на Linux. Реализация просто возвращает число байтов, которые Вы хотели записать (указанный 3-м аргументом Вашего вызова к write(2)) и игнорируете все остальное (см. этот ответ ). В зависимости от объема данных Вы пишете, и скорость целевого устройства (диск или терминал), разница в производительности может варьироваться много. Во встроенных системах, вообще говоря, отключая запись на диск путем перенаправления к /dev/null может сохранить некоторые системные ресурсы для нетривиального объема записанных данных.

, Хотя в теории, программа могла обнаружить /dev/null и выполнить некоторую оптимизацию в ограничениях стандартов, они соответствуют (ISO C и POSIX), на основе общего понимания общих реализаций, они практически не делают (т.е. Я не знаю о любой системе Unix или Linux, делающей так).

мандаты стандарта POSIX, пишущие в стандартный вывод для любого вызова к [1 110], таким образом, это не приспосабливание стандарта для подавления вызова к [1 111] в зависимости от связанных дескрипторов файлов. Для получения дополнительной информации о требованиях POSIX, можно читать ответ Damon . О, и быстрое примечание: Все дистрибутивы Linux практически совместимы POSIX, несмотря на то, чтобы не быть сертифицировал быть так.

знать, что, если Вы заменяете printf полностью, некоторые побочные эффекты могут пойти не так, как надо, например printf("%d%n", a++, &b). Если действительно необходимо подавить вывод в зависимости от среды выполнения программы, рассмотреть установку глобального флага и обернуть printf для проверки флага прежде, чем распечатать —, это не собирается замедлять программу до степени, где потеря производительности видима, как единственная проверка условия очень быстрее, чем вызов printf и выполнение всего строкового форматирования.

71
ответ дан 1 November 2019 в 10:01

printf функция будет запись к stdout. Это не соответствует для оптимизации для /dev/null. Поэтому у Вас будут издержки парсинга строки формата и оценки любых необходимых аргументов, и у Вас будет по крайней мере один syscall, плюс Вы скопирует буфер в адресное пространство ядра (который, по сравнению со стоимостью syscall незначительно).

Этот ответ основан на определенной документации POSIX.

Системные Интерфейсы
dprintf, fprintf, printf, snprintf, sprintf - печатают отформатированный вывод

fprintf (), функция должна поместить вывод в именованный поток вывода. printf () функция должен поместить вывод в поток стандартного вывода stdout. sprintf () функция должен поместить вывод, сопровождаемый пустым байтом, '\0', в последовательных байтах, запускающихся в *s; это - обязанность пользователя гарантировать, что достаточно места является свободным.

Основные Определения
должны быть
Для реализации, которая соответствует POSIX.1-2017, описывает функцию или поведение, которое обязательно. Приложение может полагаться на существование функции или поведения.

41
ответ дан 1 November 2019 в 10:01

printf функция пишет в stdout. Если дескриптор файла, подключенный с stdout, будет перенаправлен к /dev/null затем, то никакой вывод не будет записан нигде (но он будет все еще записан), но вызов к printf сам и форматирование его делает все еще произойдет.

10
ответ дан 1 November 2019 в 10:01

Запишите свое собственное, которое переносит printf () использование printf () источник как инструкция и возврат сразу, если флаг noprint установлен. Оборотная сторона этого - на самом деле печатая она использует больше ресурсов из-за необходимости проанализировать строку формата дважды. Но это использует незначительные ресурсы, если не печатающие. Не может просто заменить printf (), потому что базовые вызовы внутри printf () могут измениться с более новой версией stdio библиотеки.

пустой printf2 (символ константы *formatstring...);

5
ответ дан 1 November 2019 в 10:01

Вообще говоря, реализации разрешают выполнить такие оптимизации, если они не влияют на заметные (функциональные) выводы программы. В случае printf(), который означал бы что, если программа не использует возвращаемое значение, и если бы нет никаких %n преобразования, то реализации позволили бы ничего не сделать.

На практике, я не знаю ни о какой реализации на Linux, который в настоящее время (в начале 2019) выполняет такую оптимизацию - компиляторы и библиотеки, с которыми я знаком, отформатирует вывод и запишет результат в пустое устройство, полагаясь на ядро' для игнорирования его.

можно хотеть записать собственную передающую функцию, если действительно необходимо сохранить стоимость форматирования, когда вывод не будет использоваться - Вы захотите к нему возвратиться void, и необходимо проверить строку формата на %n. (Вы могли использовать snprintf с NULL и 0 буфер, если Вам нужны те побочные эффекты, но сбережения вряд ли возместят усилие, которое инвестируют).

4
ответ дан 1 November 2019 в 10:01

Другие вопросы по тегам:

Похожие вопросы: