Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.74/27: Рейтинг темы: голосов - 27, средняя оценка - 4.74
FiloXSee
19 / 10 / 0
Регистрация: 01.07.2011
Сообщений: 25
1

Методы оптимизации кода

01.07.2011, 07:48. Просмотров 4983. Ответов 52
Метки нет (Все метки)

Написал статью по оптимизации кода на С++. Ее можно почитать тут:
[ссылка удалена]

А вы какие еще способы оптимизации кода знаете? (я не говорю про оптимизацию алгоритмов. Речь идет про код вообще)

 Комментарий модератора 
Ссылки на сторонние ресурсы у нас и так не приветствуются, а уж битые и подавно...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2011, 07:48
Ответы с готовыми решениями:

Методы оптимизации
Здравствуйте, прошу помочь,кто может написать программу для решения задачи...

Методы оптимизации памяти
Написал статью по оптимизации памяти в программах на С++. Ее можно почитать...

Курсовая. Методы оптимизации
http://www.cyberforum.ru/attachments/402404d1400795723 Помогите чем сможете...

Методы Оптимизации: Метод параллельных касательных - нужен алгоритм
Здравствуйте. Помогите пожалуйста с составлением алгоритма по методу...

Просмотр кода после оптимизации компилятора
Здравствуйте! Известно, что компилятор оптимизирует код. А можно ли посмотреть...

52
HeRo!N
11 / 11 / 2
Регистрация: 01.10.2010
Сообщений: 139
01.07.2011, 08:10 2
Ошибка: 404

К сожалению, такой страницы не существует. Вероятно, она была удалена с сервера, либо ее здесь никогда не было.
0
FiloXSee
19 / 10 / 0
Регистрация: 01.07.2011
Сообщений: 25
01.07.2011, 08:20  [ТС] 3
Прошу прощения, вот исправленная ссылка:
http://itw66.ru/blog/c_plus_plus/13.html
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
01.07.2011, 10:00 4
Статья выглядит как СООБРАЖЕНИЯ программиста. Надо бы привести замеры времени.
0
Maxim Prishchepa
Эксперт С++
1924 / 1036 / 109
Регистрация: 29.03.2010
Сообщений: 3,167
01.07.2011, 10:38 5
Полностью соглашусь с ValeryLaptev, примеры реальной работы в студию, как на огромных так и на не очень больших массивах и т.д. и т.п.
0
dr.curse
393 / 349 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
01.07.2011, 10:49 6
C++
1
some1 = some3 * 1 / a;
а это выражение разве не эквивалентно этому?
C++
1
some1 = some3 / a;
и мне кажется что второе выполняется быстрее.
0
grizlik78
Эксперт С++
1987 / 1480 / 191
Регистрация: 29.05.2011
Сообщений: 3,059
01.07.2011, 11:13 7
Допустим есть.
C++
1
2
3
const int a = 100;
some1 = some3 * 1 / a;
some2 = some4 * 1 / a;
более эффективно написать не:
C++
1
2
3
const int a_inv = 1 / a;
some1 = some3 * a_inv;
some2 = some4 * a_inv;
а так:
C++
1
2
some1 = some3 * (1 / a);
some2 = some4 * (1 / a);
Ужас какой. Вместо последних двух строчек смело можно было написать
C++
1
2
some1 = 0;
some2 = 0;
Вот уж что наверняка будет эффективнее

Добавлено через 1 минуту
Да и во втором случае то же самое.
0
FiloXSee
19 / 10 / 0
Регистрация: 01.07.2011
Сообщений: 25
01.07.2011, 11:24  [ТС] 8
Цитата Сообщение от aram_gyumri Посмотреть сообщение
C++
1
some1 = some3 * 1 / a;
а это выражение разве не эквивалентно этому?
C++
1
some1 = some3 / a;
и мне кажется что второе выполняется быстрее.
Нет, не быстрее.

1: some1 = some3 * (1.0f / a) - в рантайме будет только умножение. деление будет делать компилятор
2: some1 = some3 / a - будет деление в рантайме. Оно медленнее умножения.
3: some1 = some3 * 1.0f / a - это то же самое что и предыдущее

вариант 1 наиболее эффективный. А заменять на a_inv не нужно, чтобы не портить читаемость кода.

Добавлено через 1 минуту
Цитата Сообщение от grizlik78 Посмотреть сообщение
Ужас какой. Вместо последних двух строчек смело можно было написать
C++
1
2
some1 = 0;
some2 = 0;
Вот уж что наверняка будет эффективнее

Добавлено через 1 минуту
Да и во втором случае то же самое.
да, ошибся. Исправил на вещественные числа.
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
01.07.2011, 11:25 9
int i;
...
x = array[ i++ ]; - более эффективно, чем
x = array[ ++i ];
сдесь дело не в эффективности, по вашему лучше допустить сознательную ошибку в программе взяв предыдущий элемент массива вместо следуещего только потому что так эффективно? что ж удачной вам отлаки

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

if( a || b) - нужно первым ставить более вероятное собятие, для большей эффективности
if( func1() && func2() ) - нужно ставить более быстрый оператор первым
аналогично и сдесь дело не в эффективности, а в приоритете, при операции || в случае истинности 1-го операнда, 2-й просто напросто не вычисляется, а при операции && в случае ложности 1-го операнда, 2-й тоже не вычисляется, но это не вычисляется != эффективно

int a[ 1000 ];
for( int i =0; i<1000; ++i )
a[ i ] = 50;

Значительно эффективнее будет:
int* p = a;
for( int i =0; i<1000; ++i, ++p )
*p = 50;
с чего бы это?

float f = 1.0f;
*(int*)&f ^= 0x80000000; - быстрее чем
f *= -1.0f;
а тут так вообще без пол-литры не разберёшся
2
grizlik78
Эксперт С++
1987 / 1480 / 191
Регистрация: 29.05.2011
Сообщений: 3,059
01.07.2011, 11:45 10
12
C
1
2
3
u32 a; f32 b;
b = (f32)(i32)a; - быстрее
b = (f32)a;
А это что ещё за магия?

Добавлено через 17 минут
В общем в этой статье нет главного, что нередко пишут в хороших книгах.
Заниматься оптимизацией стоит только тогда, когда это действительно необходимо. Ранняя "оптимизация" нередко приводит к "пессимизации" кода. Кроме того, приведённые в статье трюки могут привести к ускорению (а могут и не привести) только для конкретного процессора и конкретного компилятора. Стоит сменить то или другое, как плюсы могут неожиданно превратиться в минусы. Ну и, как уже было замечено, без реальных цифр это всё-равно ни о чём. Хотя как заметка "что ещё можно попробовать, когда ничего не помогает", может и сгодится.
2
FiloXSee
19 / 10 / 0
Регистрация: 01.07.2011
Сообщений: 25
01.07.2011, 11:48  [ТС] 11
Цитата Сообщение от Maxwe11 Посмотреть сообщение
сдесь дело не в эффективности, по вашему лучше допустить сознательную ошибку в программе взяв предыдущий элемент массива вместо следуещего только потому что так эффективно? что ж удачной вам отлаки
Да, это разные операции. Вот только программист может организовать код так, чтобы использовать любую из них.

Оптимизация алгоритма - это наиболее важная оптимизация. Но иногда нужно делать такие системы, в который каждая строчка кода может быть решающей. Тогда и нужно понимать подобные принципы.

Допустим идет разработка системы частиц (particle system). Каждая частица будет апдейтиться в каждом кадре. Если частиц 10000 то любая лишняя операция будет сказываться на производительности. А если добавить несколько if то можно вообще ее убить.

Цитата Сообщение от Maxwe11 Посмотреть сообщение
аналогично и сдесь дело не в эффективности, а в приоритете, при операции || в случае истинности 1-го операнда, 2-й просто напросто не вычисляется, а при операции && в случае ложности 1-го операнда, 2-й тоже не вычисляется, но это не вычисляется != эффективно
В данной статье под эффективностью понимается скорость выполнения. Согласись - более эффективный тот вариант, который делает меньше действий для получения результата. Значительно эффективнее код, который может не делать бесполезные действия. А самое главное, что от того как программист расположит операторы в if выражении будет зависеть скорость работы кода. Именно поэтому нужно думать, когда в if помещаешь функции. Может эта функция будет к серверу обращаться впустую только из за того, что программист поленился поставить первым оператором выражение, которое всегда вернет false.

Цитата Сообщение от Maxwe11 Посмотреть сообщение
с чего бы это?
Инкремент указателя быстрее, чем его вычисление по произвольному смещению. Именно это будет при a[x].
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
01.07.2011, 14:26 12
FiloXSee, если бы вы привели ассемблерный код в обоих случаях, то все увидели бы, что НА САМОМ ДЕЛЕ эффективно.
А пока, повторюсь, статья выглядит просто как соображения программиста. Что ОЧЕНЬ ЧАСТО не соответствует действительности.
0
diagon
Higher
1937 / 1203 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
01.07.2011, 14:28 13
Еще одной хорошей практикой является следующее:

Пусть у нас есть цикл


C++
1
2
3
for ( int i = 0; i < strlen( string ); ++i )
{
}

у нас на каждой итерации цикла вычисляется длина строки. Это плохо (за исключением когда строка в теле цикла меняется — но его мы рассматривать не будем). Лучше написать следующим образом:


C++
1
2
3
for ( int i = 0, size = strlen( string ); i < size; ++i )
{
}

И вообще — когда условие терминации цикла не меняется в ходе самого цикла (а в ином случае лучше использовать while) следует проводить предварительный расчет.
В данном случае можно сделать в 2 раза быстрее.
C++
1
2
3
for (int i = 0; str[i]; ++i)
{
}
Цитата Сообщение от pito211 Посмотреть сообщение
?????
См. #3
2
pito211
186 / 173 / 18
Регистрация: 22.03.2010
Сообщений: 612
01.07.2011, 14:30 14
Ошибка: 404

К сожалению, такой страницы не существует. Вероятно, она была удалена с сервера, либо ее здесь никогда не было.

Вернуться назад, перейти на главную
?????
0
FiloXSee
19 / 10 / 0
Регистрация: 01.07.2011
Сообщений: 25
01.07.2011, 14:53  [ТС] 15
Цитата Сообщение от diagon Посмотреть сообщение
В данном случае можно сделать в 2 раза быстрее.
C++
1
2
3
for (int i = 0; str[i]; ++i)
{
}
Спасибо за первый нормальный ответ.
Хотя это не ускорит код. Основное время тратится не на вычисление, а на условие. Его проверка остается даже в этом случае.

Более того, вариант for ( int i = 0, size = strlen( string ); i < size; ++i ) будет сравнивать две целые стековые переменные, а вариант for (int i = 0; str[i]; ++i) будет вычислять текущий указатель, разыменовывать его получая по нему данные, брать от них только 1 байт и только потом сравнивать его с нулем. Это будет дольше, чем просто сравнение.
0
diagon
Higher
1937 / 1203 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
01.07.2011, 15:01 16
Цитата Сообщение от FiloXSee Посмотреть сообщение
Спасибо за первый нормальный ответ.
Хотя это не ускорит код. Основное время тратится не на вычисление, а на условие. Его проверка остается даже в этом случае.

Более того, вариант for ( int i = 0, size = strlen( string ); i < size; ++i ) будет сравнивать две целые стековые переменные, а вариант for (int i = 0; str[i]; ++i) будет вычислять текущий указатель, разыменовывать его получая по нему данные, брать от них только 1 байт и только потом сравнивать его с нулем. Это будет дольше, чем просто сравнение.
Вы забываете о том, как работает strlen
Примерная реализация
C++
1
2
3
4
5
unsigned strlen(char * str){
    unsigned res = 0;
    while (*str++) ++res;
    return res;
}
Т.е. в этом коде
C++
1
for ( int i = 0, size = strlen( string ); i < size; ++i )
Мы пробегаем по строке 2 раза, один раз, чтобы вычислить длину.
В моем же коде пробегаем всего 1 раз.
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
01.07.2011, 15:01 17
Цитата Сообщение от FiloXSee Посмотреть сообщение
Спасибо за первый нормальный ответ.
Хотя это не ускорит код. Основное время тратится не на вычисление, а на условие. Его проверка остается даже в этом случае.

Более того, вариант for ( int i = 0, size = strlen( string ); i < size; ++i ) будет сравнивать две целые стековые переменные, а вариант for (int i = 0; str[i]; ++i) будет вычислять текущий указатель, разыменовывать его получая по нему данные, брать от них только 1 байт и только потом сравнивать его с нулем. Это будет дольше, чем просто сравнение.
Это опять-таки только ВАШИ соображения. Покажите ассемблерный текст для обоих вариантов.
1
voral
864 / 571 / 122
Регистрация: 16.03.2008
Сообщений: 2,670
01.07.2011, 15:15 18
Цитата Сообщение от FiloXSee Посмотреть сообщение
Да, это разные операции. Вот только программист может организовать код так, чтобы использовать любую из них.
Две этих строки (с постфиксом и префиксом) сравнивать совершенно не корректно, т.к. они не взаимозаменяемы.
0
FiloXSee
19 / 10 / 0
Регистрация: 01.07.2011
Сообщений: 25
01.07.2011, 15:27  [ТС] 19
Цитата Сообщение от diagon Посмотреть сообщение
Мы пробегаем по строке 2 раза, один раз, чтобы вычислить длину.
В моем же коде пробегаем всего 1 раз.
Да, видимо там не очень удачный комментарий. Видимо комментатор там имел в виду, что нужно выносить все сложные вычисления из части условия в раздел объявления переменных, чтобы вычислять верхний предел один раз.

Добавлено через 3 минуты
Цитата Сообщение от voral Посмотреть сообщение
Две этих строки (с постфиксом и префиксом) сравнивать совершенно не корректно, т.к. они не взаимозаменяемы.
Сравнивать можно что угодно. Важно то, как это используется. Понятно что эти строчки не взаимозаменяемые. Но всегда можно реорганизовать код для любой из этих форм записи. Вопрос в том, какую форму в каких случаях лучше использовать.
0
voral
864 / 571 / 122
Регистрация: 16.03.2008
Сообщений: 2,670
01.07.2011, 15:34 20
Просто тогда явно не хватает сравнения что лучше
C
1
x=array[i++]
или
C
1
2
x=array[i];
++i;
и отдельно
C
1
x=array[++i]
или
C
1
2
++i;
 x=array[i];
0
01.07.2011, 15:34
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.07.2011, 15:34

Объяснить нюансы оптимизации заданного фрагмента кода
Наткнулся на статью по оптимизации кода на...

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

Мешает ли разделение кода на объявление (.h) и определение (.cpp) inline оптимизации?
Читал что когда включают хедер но не реализацию в единицу трансляции, это...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru