Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.06.2013, 16:16   #1
Shad0wF1rst
Форумчанин
 
Регистрация: 11.01.2013
Сообщений: 149
По умолчанию Не большой вопрос по оптимизации

Как сильно влияет на производительность проверки находящиеся в цикле?

1) Речь идет об огромных циклах.
2) Проверка осуществляется следующим образом, если найдется хоть один параметр удовлетворяющий условию, то происходит выход из цикла.
3) Расстраивается крайний случай, когда параметр удовлетворяющий условию находится в конце цикла.
Может это и чушь, но это моя чушь и я ее никому не отдам.
Shad0wF1rst вне форума Ответить с цитированием
Старый 05.06.2013, 16:20   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Что-то не очень понятно. Влияют - по сравнению с какой альтернативой? Хотя бы в общих чертах пример можно?
Abstraction вне форума Ответить с цитированием
Старый 05.06.2013, 16:55   #3
Shad0wF1rst
Форумчанин
 
Регистрация: 11.01.2013
Сообщений: 149
По умолчанию

Вот две ситуации
1)
Код:
char mass[1000000000];
for (int i = 0; i < 1000000000; i++) {
if (mass[i] == 10) return значение;
какие нибудь еще операции
}
return значение;
2)
Код:
for (int i = 0; i < 1000000000; i++) {
какие нибудь еще операции
}
return значение;
Все соответственно упращенно.
Может это и чушь, но это моя чушь и я ее никому не отдам.

Последний раз редактировалось Stilet; 06.06.2013 в 12:16.
Shad0wF1rst вне форума Ответить с цитированием
Старый 05.06.2013, 17:01   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Второе предпочтительнее только в том случае, если вероятность срабатывания условия архимизерная (и, разумеется, блоки функционально эквивалентны). Одна проверка - это быстро, особенно в относительном выражении.
Но, разумеется, насколько-то выполнение итерации цикла при этом замедляется. Я бы сказал, что первый вариант универсальнее, а потому до тестов производительности предпочтительнее.
Abstraction вне форума Ответить с цитированием
Старый 06.06.2013, 09:20   #5
Shad0wF1rst
Форумчанин
 
Регистрация: 11.01.2013
Сообщений: 149
По умолчанию

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

Код:
bool function (char *buffer)
{
    for (int i = 0; i < 22; i++) {
        if (buffer[i] != 0) return true;
    }
    return false;
}
тут я думаю объяснять ничего не надо.
Предлагаю заменить ее на такую. Сразу скажу что не пробовал ее еще но все же.

Код:
bool function (char *buffer)
{
    int i = 22;
    while (!buffer[i] ^ !i);
    return (i > 0 || buffer[0] != 0);
}
Ну вот если че не понятно могу пояснить)))
Блин тут опечатался строчку while (!buffer[i] ^ !i); заменить на while (!buffer[--i] ^ !i); а то все зациклится)))
Может это и чушь, но это моя чушь и я ее никому не отдам.

Последний раз редактировалось Stilet; 06.06.2013 в 12:17. Причина: Опечатка.
Shad0wF1rst вне форума Ответить с цитированием
Старый 06.06.2013, 09:50   #6
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

В идеале, функция
Код:
bool function (char *buffer)
 {
 int i = 22;
 while (!buffer[i] ^ !i);
 return (i > 0 || buffer[0] != 0);
 }
Будет работать быстрее.
Почему? Потому, что не имеет внутреннего счётчика итераций.
Функцию while, можно рассматривать как:
Код:
1: if(); 
.........
goto 1;
Тогда как for, рассматривается как

Код:
int i;
1:// исполняемые операторы
i=i+1;
if(i<N) goto 1;
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 06.06.2013, 10:01   #7
Shad0wF1rst
Форумчанин
 
Регистрация: 11.01.2013
Сообщений: 149
По умолчанию

К этому и шел. Конечно с небольшими массивами это не заметно будет что работать будет быстрее, но иногда приятно просто по напрягать мозги и придумать подобные извраты не зацикливаясь на шаблонах.
Может это и чушь, но это моя чушь и я ее никому не отдам.
Shad0wF1rst вне форума Ответить с цитированием
Старый 06.06.2013, 11:58   #8
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Код:
while (!buffer[--i] ^ !i);
Не хорошо. Имеете все шансы уйти за пределы массива.
В любом случае, такого рода оптимизации находятся скорее в ведении оптимизатора. Вы не избавляетесь от проверки, Вы переносите её в другое место. Если извращаться, то мой вариант:
Код:
bool IsNotAll0(const char *buffer)
{
for (const char* cur = buffer+22; cur!=buffer; ) if(*--cur != 0) return true;
return false;
}
А теперь в четыре раза быстрее:
Код:
bool IsNotAll0(const char *buffer)
{
for (const int* cur = (const int*)buffer+4; cur!=buffer; ) if(*--cur != 0) return true;
return buffer[20]!=0 || buffer[21]!=0;
}
Abstraction вне форума Ответить с цитированием
Старый 06.06.2013, 12:09   #9
Shad0wF1rst
Форумчанин
 
Регистрация: 11.01.2013
Сообщений: 149
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Код:
while (!buffer[--i] ^ !i);
Не хорошо. Имеете все шансы уйти за пределы массива.
В любом случае, такого рода оптимизации находятся скорее в ведении оптимизатора. Вы не избавляетесь от проверки, Вы переносите её в другое место. Если извращаться, то мой вариант:
Код:
bool IsNotAll0(const char *buffer)
{
for (const char* cur = buffer+22; cur!=buffer; ) if(*--cur != 0) return true;
return false;
}
А теперь в четыре раза быстрее:
Код:
bool IsNotAll0(const char *buffer)
{
for (const int* cur = (const int*)buffer+4; cur!=buffer; ) if(*--cur != 0) return true;
return buffer[20]!=0 || buffer[21]!=0;
}
Я кстати думал насчет использования long, да так быстрее, но не так интересно потому что очевидно))). А вот насчет замечания что выйдет за приделы массива я поясню ту запись !buffer[--i] ^ !i;
Предположим когда мы проходим по массиву у нас содержимое его нули и тогда получаем что эта запись имеет следующий вид true ^ false = true;
следующий случай когда все таки встречается в массиве не ноль тогда получаем false ^ flase = flase и успешно выходим из цикла.
И последний случай когда когда все таки все нули в массиве, то есть buffer[0] = 0, тогда получаем true ^ true = false и также успешно выходим из цикла, по этому не вижу никаких выходов за приделы массива.
Может я не все варианты рассмотрел и чего то не учел, буду рад узнать о них)))
Может это и чушь, но это моя чушь и я ее никому не отдам.
Shad0wF1rst вне форума Ответить с цитированием
Старый 06.06.2013, 12:15   #10
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Может я не все варианты рассмотрел и чего то не учел, буду рад узнать о них)))
Не учли, что ^ - поразрядный оператор. false - это 0, true - это что угодно кроме 0. Поэтому true^true равно, вообще говоря, чему угодно.
Abstraction вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не большой вопрос по модулю GRAPH An4ix.Murad Паскаль, Turbo Pascal, PascalABC.NET 1 29.05.2012 21:29
Не большой вопрос ziganurov2011 Паскаль, Turbo Pascal, PascalABC.NET 8 22.07.2011 22:31
Вопрос оптимизации работы с MS Word Mixasik Общие вопросы Delphi 1 15.06.2009 12:13
Вопрос оптимизации программы на С++ argrus Помощь студентам 9 29.03.2008 23:54