2014-12-30 3 views
2

В коде C, какЯвляется ли fputs более эффективным, чем формат («% s», ..)?

printf("%s", message); 

Интересно, должен ли я предпочитаю использовать

fputs(message, stdout); 

Прежний код лучше, но это он медленнее? или использует больше памяти? Я предпочитаю более четкий код, но не тогда, когда он выглядит как потерянное время & память глупо.

Я хотел бы знать, что компилятор обнаруживает такие ситуации и что необходимый синтаксический анализ и интерпретация формата не выполняется во время выполнения. В конце концов, gcc жалуется на printf(""), поэтому компиляторы могут «понимать» форматы и предварительно обрабатывать их.

PS: что прежний стиль более ясен, при написании format("name=%s\n",unameData.nodename); вместо fputs(stdout,"name=");fputs(stdout,unameData.nodename);putchar('\n');. Это, в конце концов, назначение форматов.

+0

Пробовали ли вы несколько тестовых прецедентов для проверки времени выполнения каждой опции? Если у вас есть, может быть полезно опубликовать их здесь. В противном случае, как вы знаете наверняка, что он медленнее, чем другой? –

+3

Бенчмарк! Делайте оба миллиона раз и смотрите. Не то, чтобы это имело значение в любом случае, так как сами функции не будут те, которые занимают все время, а фактический вывод на терминал. –

+0

Чистый код почти всегда лучше, чем эффективный код, поэтому оптимизируйте узкие места, если вам нужно, но в других случаях читайте. – meskobalazs

ответ

5

Один или другой может быть более эффективным в зависимости от реализации.

При правильном значении оптимизации достойный компилятор должен иметь возможность изменять менее эффективную форму в другую (предполагая printf("%s\n", message)) без знаний программиста.

$ cat print.c 
#include <stdio.h> 

int main() 
{ 
    printf("%s\n", "Hello world"); 
    return 0; 
} 

$ gcc -S -O2 print.c 
$ cat print.s 
    .file "print.c" 
    .section .rodata.str1.1,"aMS",@progbits,1 
.LC0: 
    .string "Hello world" 
    ... 
    movl $.LC0, (%esp) 
    call puts 
    xorl %eax, %eax 
    leave 
    ... 

... представляет код для краткости опускает

+1

1.0E99 спасибо! Я никогда не использовал gcc -S, но ваш пример показывает, как его можно использовать. – phs

2

Хотя в теории либо может быть правильным, на практике printf функции почти всегда имеет более высокую стоимость:

  • printf функция являются переменными функциями аргумента, который ограничивает использование компилятором вызывающих соглашений. Это приводит к большему использованию памяти программы, так как очистка всегда выполняется по коду вызывающего абонента. Код также может быть медленнее, поскольку параметры должны передаваться в стек вместо регистров.

  • printf Функции имеют тенденцию к значительному увеличению использования стека из-за сложного характера этих функций.

Хотя некоторый компилятор может обнаружить printf и использовать puts вместо где это возможно, в компиляторах практики для встраиваемых систем не всегда умные, и в этой среде разница действительно имеет значения.

Смежные вопросы