всегда ли быстрее хранить несколько вызовов классов в переменной? - PullRequest
1 голос
/ 06 января 2012

Если у вас есть такой метод:

float method(myClass foo)
{
    return foo.PrivateVar() + foo.PrivateVar();
}

всегда ли это быстрее / лучше делать вместо этого?:

float method(myClass foo)
{
    float temp = foo.PrivateVar();
    return temp + temp;
}

Я знаю, что вы не должны помещать вызов типа foo.PrivateVar() в цикл for, например, потому что он оценивает его много раз, когда вам действительно нужно использовать значение только один раз (в некоторых случаях.

for (int i = 0; i < foo.PrivateInt(); i++)
{
    //iterate through stuff with 'i'
}

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

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

1 Ответ

4 голосов
/ 06 января 2012

Это полностью зависит от того, что делает PrivateVar(), где он определен и т. Д. Если у компилятора есть доступ к коду в PrivateVar() и он может гарантировать отсутствие побочных эффектов, вызывая функцию, которую он может выполнять CSE, которая являетсяв основном то, что вы сделали во втором примере кода.

Точно так же верно и для цикла for.Поэтому, если вы хотите быть уверенным, что она оценивается только один раз, потому что это очень дорогая функция (что также означает, что гарантировать отсутствие побочных эффектов сложно, даже если их нет), напишите ее явно.

Если PrivateVar() просто получатель, напишите более понятный код - даже если компилятор может не делать CSE, разница в производительности не будет иметь значения в 99,9999% всех случаев.

Редактировать: CSE означает Устранение общего выражения Sube и делает именно то, что обозначает;) На вики-странице показан пример простого умножения, но мы можем сделать это и для больших конструкций кода, например, для вызова функции.

Во всех случаях мы должны гарантировать, что только однократная оценка кода не изменит семантику, то есть выполнение CSE для этого кода:

a = b++ * c + g;
d = b++ * c * d;

и изменение его на:

tmp = b++ * c;
a = tmp + g;
d = tmp * d;

, очевидно, будет недопустимым (для вызовов функций это, очевидно, немного сложнее, но это тот же принцип).

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