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 ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.