script O printf ainda terá um custo mesmo se eu redirecionar a saída para/dev/null?



shell script stress test (4)

A função printf grava no stdout . Se o descritor de arquivo conectado ao stdout for redirecionado para /dev/null , nenhuma saída será gravada em lugar algum (mas ela ainda será gravada), mas a chamada para printf e a formatação ainda ocorrerão.

https://ffff65535.com

Nós temos um daemon que contém muitas mensagens impressas. Como estamos trabalhando em um dispositivo embarcado com um CPU fraco e outro hardware de restrição, queremos minimizar qualquer tipo de custo (E / S, CPU, etc.) de mensagens printf em nossa versão final. (Usuários não possuem console)

Meu companheiro de equipe e eu tenho um desentendimento. Ele acha que podemos apenas redirecionar tudo para / dev / null. Não vai custar nenhum IO, então as afinidades serão mínimas. Mas acho que ainda custará CPU e é melhor definirmos uma macro para printf, para que possamos reescrever "printf" (talvez apenas retornar).

Então eu preciso de algumas opiniões sobre quem está certo. O Linux será inteligente o suficiente para otimizar o printf? Eu realmente duvido disso.


A função printf irá gravar no stdout . Não está em conformidade para otimizar /dev/null . Portanto, você terá a sobrecarga de analisar a string de formato e avaliar quaisquer argumentos necessários, e você terá pelo menos um syscall, além de copiar um buffer para o espaço de endereço do kernel (o que, comparado ao custo do syscall é neglegível) .

Esta resposta é baseada na documentação específica do POSIX.

Interfaces do sistema
dprintf, fprintf, printf, snprintf, sprintf - imprimir saída formatada

A função fprintf () deve colocar a saída no fluxo de saída nomeado. A função printf () deve colocar a saída no stdout do fluxo de saída padrão. A função sprintf () deve colocar a saída seguida do byte nulo, '\ 0', em bytes consecutivos começando em * s; É responsabilidade do usuário garantir que haja espaço suficiente disponível.

Definições Base
deve
Para uma implementação em conformidade com POSIX.1-2017, descreve um recurso ou comportamento que é obrigatório. Um aplicativo pode confiar na existência do recurso ou comportamento.


De um modo geral, uma implementação pode realizar essas otimizações se elas não afetarem os resultados (funcionais) observáveis ​​do programa. No caso de printf() , isso significaria que, se o programa não usa o valor de retorno, e se não houver %n conversões, a implementação não poderia fazer nada.

Na prática, não tenho conhecimento de nenhuma implementação no Linux que atualmente (início de 2019) realiza essa otimização - os compiladores e bibliotecas com os quais estou familiarizado irão formatar a saída e gravar o resultado no dispositivo nulo, contando com o kernel 'para ignorá-lo.

Você pode escrever uma função de encaminhamento se realmente precisar economizar o custo de formatação quando a saída não for usada - você desejará que ela retorne void e você deve verificar a string de formato para %n . (Você pode usar o snprintf com um buffer NULL e 0 se precisar desses efeitos colaterais, mas é improvável que as economias compensem o esforço investido).


Escreva o seu próprio que envolve printf () usando a fonte printf () como uma diretriz, e retornando imediatamente se um flag noprint estiver definido. A desvantagem disso é que, na verdade, a impressão consumirá mais recursos por causa da necessidade de analisar a sequência de formatações duas vezes. Mas usa recursos insignificantes quando não está imprimindo. Não é possível simplesmente substituir printf () porque as chamadas subjacentes dentro de printf () podem mudar com uma versão mais nova da biblioteca stdio.

void printf2 (const char * formatstring, ...);





dev-null