LINUX.ORG.RU
ФорумTalks

Оптимизация вызовов strlen


0

0
Вопрос: должен ли компилятор пытаться преобразовать

for(i = 0; i < strlen(str); i++)

во что-нибудь вида

for(i = 0; str[i]; i++)

?

Я считаю, что не должен - даже если видно, что операторы внутри цикла не изменяют длину строки (и строка не volatile).

Если пользователю охота превратить линейную сложность в квадратичную - его право. А дело компилятора - выдать предупреждение. "Вы вот здесь поставили strlen, а он не нужен. Потрудитесь убрать, а то вдруг будете компилировать другим компилятором, а он такого не скажет."
★★★
А я считаю, что нужно. Иначе зачем тогда вообще оптимизация?

Но предупреждение надо выдавать обязательно.

blaster999 ★★
()
Пока оптимизации не влияют на семантику - компилятор может делать что угодно.

И ворнинги оптимизации не помеха.

Legioner ★★★★★
()
Конечно не должен.
Deleted
()
Кстати, когда я учился в универе, были в нашей группе умники, которые умудрялись такое писать... Например, есть массив чисел, надо найти минимальное и максимальное число. Так это горе-кодеры искали минимум и максимум в отдельных циклах.
blaster999 ★★
()
а менять памперс пользователю такой компилятор будет?
anonymous
()
Подобная оптимизация - это бред.
Тут уже написали про комбайн, заменяющий тампексы у программиста.
pacify ★★★★★
()
Ответ на: комментарий от pacify
критичные участки нужно писать грамотно - тогда память течь не будет
Muromec ☆☆
()
Сейчас попробовал "скомпилировать" в ассемблер вот такую программу:

#include <stdio.h>
#include <string.h>

int main ()
{
    char *s = "Test";
    int i;

    for(i = 0; i < strlen(s); i++)
    {
        printf("%c\n", s[i]);
    }
}

И как вариант, её же, но с s[i] вместо strlen.

Выяснилось, что по умолчанию GCC не "оптимизирует" strlen в предложенном смысле, а честно заменяет на цикл. Причём всегда подставляет функцию вместо её вызова, даже при -O0.

А вот с -O3 - таки да, оптимизирует...
Sikon ★★★
() автор топика
Ответ на: комментарий от Sikon
>Выяснилось, что по умолчанию

по умолчанию gcc использует "-O0" то без любых оптимизаций
fghj ★★★★★
()
Что за бред? Кто в здравом уме будет узнавать длину неизменяемой строки в цикле?
anonymous
()
Ответ на: комментарий от Sikon
> с -O3 - таки да, оптимизирует...

Теперь объяви переменную вот так:

char * volatile s = "Test";

и посмотри результат.

Оптимизатор делает чо сказано, мыслёв читать не обученный он.

anonymous
()
А что - компилятор должен знать детали реализации функции (в общем случае)? Если это, конечно, не встроенная функция.
svu ★★★★★
()
Ответ на: комментарий от svu
> А что - компилятор должен знать детали реализации функции (в общем случае)? Если это, конечно, не встроенная функция.

Вообще должен бы знать. Не программиста же этим заморачивать..

anonymous
()
Ответ на: комментарий от svu
Теоретически - может подставить в цикл (заинлайнить) и потом вынести из цикла инварианты.

Практически - про strlen скорее всего знает.

Legioner ★★★★★
()
Ответ на: комментарий от svu
> Машина должна работать, человек - думать.

Сходить в библиотеку и посмотреть не зависит ли данная функция на чём-нить волатильном - это "работать" или "думать"?

anonymous
()
Я сейчас открою страшную тайну: на ЛОРовском форуме помимо раздела "Talks" существует раздел "Development", предназначенный (кто бы мог подумать??) для вопросов, касающихся программирования.
MYMUR ★★★★
()
Ответ на: комментарий от MYMUR
> Я сейчас открою страшную тайну: на ЛОРовском форуме помимо раздела "Talks" суще

Типа умный нах?

anonymous
()
Ответ на: комментарий от Legioner
> Теоретически - может подставить в цикл (заинлайнить) и потом вынести из цикла инварианты.

Кстати, может быть и так.

Sikon ★★★
() автор топика
Ответ на: комментарий от svu
> А что - компилятор должен знать детали реализации функции (в общем случае)? Если это, конечно, не встроенная функция.

В общем случае - нет.

В частности, замена strlen на обёртку над ней приводит к вызову этой обёртки на каждой итерации. Но внутри обёртки strlen всё равно инлайнится.

Кстати, это идея - объявить обёртку inline и посмотреть, сумеет ли компилятор вынести её из цикла при -O3.

Sikon ★★★
() автор топика
компилятор не только может, но и должен делать оптимизацию простирающуюся за пределами одной функции. Разумеется если он знает что делает данная функция.

Он знает что делает данная функция в 2 случаях -- он видит ее код (например она инлайн), либо она есть в стандарте и ты инклюдишь стандартный хедер который ее объявляет.

Таким образом он может и должен делать оптимизацию strlen

dilmah ★★★★★
()
Ответ на: комментарий от Sikon
> замена strlen на обёртку над ней приводит к вызову этой обёртки на каждой итерации.

Это при -O3 ????

anonymous
()
#include <stdio.h>

#include <string.h>

int main() {

char str[255];

int i;

strcpy(str, "Hello World!!!\n");

int puk_puk_puk = strlen(str);

for(i = 0; i < puk_puk_puk; i++) {

printf("%c|", str[i]);

}

return 0;

}

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

phasma ★☆
()
Хм. Пользователь в цикле может удалить строку и выделить под нее новую (большую или меньшую) внутри цикла. Теоретически это возможно, тем более это может происходить не в тексте программы, а при передачи указателя на строку в какую-нибудь неизвестную функцию из разделяемой библиотеки... Так что strlen необходим.

А вообще, for(i = 0; i < m; i++) это тоже глупо. Надо писать for(p = str; p < str_end; p++) , т.к. { p++ } - быстрее чем { i++; p[i] }

1) i++ - лишняя операция inc

2) p[i] <==> *(p+i) - целая операция add!

xTERM ★★
()
Ответ на: комментарий от xTERM
Необходим всмысле, что компилятор его не удаляет.
xTERM ★★
()
Ответ на: комментарий от xTERM
> 1) i++ - лишняя операция inc

> 2) p[i] <==> *(p+i) - целая операция add!

Просто из интереса скомпилируй и посмотри где там эти операции будут при -O3 :-D

anonymous
()
Ответ на: комментарий от anonymous
A *working*compiler* is better than broken code.

There's no way to use volatile for these things, since it can hit *anything*. When the compiler generates buggy code, it's buggy code. We can't add volatiles to every single data structure. We'd be better off having a million monkeys on crack try to hand-assemble the thing, than having a totally buggy compiler do it for us.

Linus

anonymous
()
Ответ на: комментарий от Sikon
Ничего подобного, если просто обертку пририсовать.
anonymous
()
Ответ на: комментарий от xTERM
> http://gcc.gnu.org/ml/gcc/2007-10/msg00266.html

Ну так чо, есть же специальное слово, которым обозначаются переменные, значение которых может быть изменено извне потока команд. Если слово не сказано - значит автор программы сам себе ЗБ.

anonymous
()
Ответ на: комментарий от blaster999
> А я считаю, что нужно.

А потом у тебя появится вторая нить которая изменит str...

no-dashi ★★★★★
()
Ответ на: комментарий от anonymous
>Типа умный нах?

Типа того. А ты чо такой дерзкий? Какова сраёна??

MYMUR ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.