Как создать ярлык переменной
Предположим, мне нужно создать сложную математическую формулу, например
double f(double array1[100], double array2[100])
{
double z = array1[21] * array2[3] + array[10];
double q = array1[21] * array1[30] / array1[10];
return array1[1] * z * q;
}
или более сложным. Мое решение заключается в создании промежуточных переменных, таких как:
double f(double array1[100], double array2[100])
{
double energy = array1[21];
double mass = array2[3];
double speed = array[10];
double z = energy * mass + speed;
double q = energy * array[30] / speed;
return array1[1] * z * q;
}
проблема в том, что мне действительно не нужна эта новая переменная, и я не хочу тратить память или увеличивать время для вызова функции. Поэтому теперь я использую const
для каждой промежуточной переменной, поэтому, возможно, компилятор более склонен ее оптимизировать. Но, может быть, лучше использовать ссылки?
Ответы
Ответ 1
gcc-llvm со стандартной оптимизацией: результаты идентичны, игнорируя переупорядочение команд
define double @_Z1fPdS_(double* nocapture %array1, double* nocapture %array2) nounwind readonly {
entry:
%0 = getelementptr inbounds double* %array1, i64 21 ; <double*> [#uses=1]
%1 = load double* %0, align 8 ; <double> [#uses=2]
%2 = getelementptr inbounds double* %array2, i64 3 ; <double*> [#uses=1]
%3 = load double* %2, align 8 ; <double> [#uses=1]
%4 = fmul double %1, %3 ; <double> [#uses=1]
%5 = getelementptr inbounds double* %array1, i64 10 ; <double*> [#uses=1]
%6 = load double* %5, align 8 ; <double> [#uses=2]
%7 = fadd double %4, %6 ; <double> [#uses=1]
%8 = getelementptr inbounds double* %array1, i64 30 ; <double*> [#uses=1]
%9 = load double* %8, align 8 ; <double> [#uses=1]
%10 = fmul double %1, %9 ; <double> [#uses=1]
%11 = fdiv double %10, %6 ; <double> [#uses=1]
%12 = getelementptr inbounds double* %array1, i64 1 ; <double*> [#uses=1]
%13 = load double* %12, align 8 ; <double> [#uses=1]
%14 = fmul double %13, %7 ; <double> [#uses=1]
%15 = fmul double %14, %11 ; <double> [#uses=1]
ret double %15
}
define double @_Z2f2PdS_(double* nocapture %array1, double* nocapture %array2) nounwind readonly {
entry:
%0 = getelementptr inbounds double* %array1, i64 21 ; <double*> [#uses=1]
%1 = load double* %0, align 8 ; <double> [#uses=2]
%2 = getelementptr inbounds double* %array2, i64 3 ; <double*> [#uses=1]
%3 = load double* %2, align 8 ; <double> [#uses=1]
%4 = getelementptr inbounds double* %array1, i64 10 ; <double*> [#uses=1]
%5 = load double* %4, align 8 ; <double> [#uses=2]
%6 = fmul double %1, %3 ; <double> [#uses=1]
%7 = fadd double %6, %5 ; <double> [#uses=1]
%8 = getelementptr inbounds double* %array1, i64 30 ; <double*> [#uses=1]
%9 = load double* %8, align 8 ; <double> [#uses=1]
%10 = fmul double %9, %1 ; <double> [#uses=1]
%11 = fdiv double %10, %5 ; <double> [#uses=1]
%12 = getelementptr inbounds double* %array1, i64 1 ; <double*> [#uses=1]
%13 = load double* %12, align 8 ; <double> [#uses=1]
%14 = fmul double %13, %7 ; <double> [#uses=1]
%15 = fmul double %14, %11 ; <double> [#uses=1]
ret double %15
}
Ответ 2
- Создайте ваше приложение таким образом, чтобы он не мешал быстрому коду.
- Напишите свой код, чтобы он был легко читаемым и поддерживаемым.
- Правильно выполните .
- Попробуйте узнать, слишком ли он медленный.
- Если это так, профайл, чтобы увидеть, где он проводит большую часть своего времени.
- Посмотрите на эти области, чтобы узнать, можно ли повысить производительность при использовании улучшенных алгоритмов.
- Если все остальное терпит неудачу (и только после этого), начните настраивать код так, как вы просите, в местах, где профилирование оказалось релевантным для приложений Общая производительность. Обычно это будет очень мало пятен.
Ответ 3
Я бы начал передавать два входных массива указателем const или ссылкой const.
Я не думаю, что это отличная идея, есть функция, подобная вашему примеру, я не знаю, является ли это просто примером или реальным кодом. Я думаю, что разница в производительности очень минимальна, и гораздо лучше создать код, который легко читать.
Чтобы ответить на ваш вопрос: избегайте временного объекта, если это возможно, поэтому используйте ссылку. Используйте ключевое слово const, если логически имеет смысл, что переменная является константой, а не по соображениям производительности.
Улучшите скорость сразу после профилирования.
Ответ 4
С любым достойным компилятором я очень сомневаюсь, что это важно.
Для локальных переменных, где вы не берете адрес переменной где-либо, компилятор сможет увидеть, что они используются только в этой функции как временные и оптимизируют их. Они почти certanly не будут занимать какую-либо память или создавать какой-либо код, который не был бы необходим в любом случае.
Я сомневаюсь, что объявление их const будет иметь какое-либо значение, и если вы сделаете их ссылкой, то они все равно должны быть ссылкой на "что-то".
Честно говоря, я не стал бы об этом беспокоиться, просто напишите, какой код выглядит наиболее естественным, и пусть компилятор выполнит эту работу.
Ответ 5
Если вы используете несколько переменных для своей функции foreach, которую вы вызываете в методе, вам необходимо выделить пространство в стеке для них, а для использования foreach вам может понадобиться перейти в память, чтобы получить значения, делая несколько переменных более неэффективными,
Вероятно, компилятор достаточно умен, чтобы избежать лишних чтений и записи в памяти, но если вам не нужны дополнительные переменные, не используйте его, но если ваш код более явственен с использованием нескольких переменных, используйте их, потому что, возможно, компилятор делает все smot.
Ответ 6
Я бы занялся этим несколько иначе.
Если вы хотите сделать его более читаемым, почему бы не определить некоторые константы
static const unsigned int energy = 21;
static const unsigned int speed = 10;
static const unsigned int mass = 3;
double z = array1[energy] * array2[mass] + array[speed];
double q = array1[energy] * array1[30] / array1[speed];
return array1[1] * z * q;
Индексные переменные могут быть определены глобально.
Что означают значения в 1 и 30?
Я вижу, что есть другой массив переменных, который вы не определяете.