Есть ли разница в производительности с этими типами инициализации переменных? - PullRequest
2 голосов
/ 27 января 2012

В локальной области (например, функция), учитывая эти 4 примера:

(1)

int x;
int y;
// code...
x = 4;
y = 5;

(2)

int x = 4;
int y = 5;
// code...

(3)

// code...
int x = 4;
// code...
int y = 5;

(4)

// any other possibility

Существует некоторая разница в производительности в форме, которую я объявляю и инициирую для своих переменных, или компиляция отслеживает это для меня?

Редактировать

Я спрашиваю, потому что я часто читал, что лучше поместить все объявления в самые первые строки, которые были бы лучше для производительности. Как:

func(){
    int x,y,z,w;
    long bla,ble;
    MYTYPE weeee;
    // more declarations..
    //code..
}

Но я не знал почему.

Ответы [ 8 ]

3 голосов
/ 27 января 2012

C ничего не говорит о производительности.

(C99, 5.1.2.3p1) «Семантические описания в этом международном стандарте описывают поведение абстрактной машины, в которой вопросы оптимизации не имеют значения»

Это зависит от реализации, но любой хороший компилятор, скорее всего, выдаст тот же код.

1 голос
/ 27 января 2012

Я спрашиваю, потому что я часто читал, что лучше поместить все объявления в самые первые строки, которые были бы лучше для производительности. Как:

func(){
    int x,y,z,w;
    long bla,ble;
    MYTYPE weeee;
    // more declarations..
    //code..
}

Нет, единственная причина для этого состоит в том, что в раннем C у вас было , чтобы поместить все объявления перед кодом в функции.

Это правило было изменено в конце прошлого века.

1 голос
/ 27 января 2012

1) Там будет - в отладке . Компилятор должен позаботиться о вас в релизе.

2) Вы можете предпочесть это для удобства чтения. Компилятор может полностью стереть постоянное значение.

3) Это может иметь значение. Локальные объявления часто лучше, но это более важно в C ++, где фактические конструкторы выполняют некоторую работу. Иногда вы можете измерить разницу, если большой объект извлечен из цикла (но ваш компилятор должен сделать это за вас).

Я спрашиваю, потому что я часто читал, что лучше поместить все объявления в самые первые строки, которые были бы лучше для производительности.

Не так. Я полагаю, что эта идея просто исходит из языковых ограничений прошлых лет. В любом случае, «как можно более локально» регулярно лучше. Конечно, это может варьироваться в зависимости от компилятора, аппаратного обеспечения, реализаций и т. Д.

В C распределение и инициализация стека тривиальны, и ваш компилятор должен справиться с этим достаточно хорошо, чтобы производительность в большинстве случаев не беспокоила.

Попробуйте реальный сравнительный анализ и профилирование. Просмотр asm (как сказал Экс) также может помочь.

Если вы не занимаетесь написанием ассемблера и не выполняете ежедневное профилирование, и это строго C, то не стоит менять способ написания.

1 голос
/ 27 января 2012

Я спрашиваю, потому что я часто читал, что лучше поместить все объявления в самые первые строки, которые были бы лучше для производительности.

Я могу заверить вас, что это чепуха. Люди, делающие такие заявления, не имеют ни малейшего представления, как код C переводится в машинный код.

Я был бы очень удивлен, если бы любой из ваших трех примеров давал другой машинный код.


Однако существует особый случай: если бы переменные были объявлены как "глобальные" или статические, то они имели бы статическую продолжительность хранения. И тогда они будут инициализированы до вызова main (). Все глобальные переменные / статика, которые не были явно инициализированы программистом, установлены в ноль. Так что в этом случае ваш пример 1) был бы медленнее:

int x; /* global variable, no explicit init so it will get set to 
          zero before main() is called */
...
x = 4; // variable gets set a second time, elsewhere, in "runtime"

медленнее, чем

int x = 4; // global variable, gets initialized before main() is called

Разница в производительности между этими двумя, тем не менее, скорее всего всего одна инструкция CPU, поэтому в 99,9% всех приложений это не имеет значения.

1 голос
/ 27 января 2012

Если ни один из блоков // code не коснется x и y, маловероятно, что вы заметите ощутимую разницу в производительности между этими опциями.

Если вы хотите точно знать, что происходит на вашей аппаратной архитектуре с использованием вашего компилятора, вы всегда можете сравнить код и / или проверить сгенерированную сборку.

0 голосов
/ 27 января 2012

В Си, я не думаю, что это будет иметь значение. В C ++ (не заданный вопрос, который я знаю), вы получаете существенные различия в зависимости от того, вызваны ли конструкторы, и если временный объект объявлен внутри цикла, сколько раз они были вызваны.

В C99 я не уверен, выделяют ли поздние объявления место в стеке при вводе функции или при вводе блока. Это будет иметь аналогичные, хотя и незначительные, последствия для производительности, с которыми должен работать оптимизатор. Согласно ответу Экс, хороший подход - это посмотреть на ассемблер, чтобы увидеть, что происходит под капотом,

0 голосов
/ 27 января 2012

Если компилятор действительно тупой, вторая форма - лучшая.Иначе, это оптимизирует другие формы к нему.

0 голосов
/ 27 января 2012

Нет универсально предсказуемой разницы в производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...