@MrBman

И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

В общем суть такая, есть код:
int str_cmp1(const char *s, const char *t)
{
    while (*s == *t && *s != '\0')
        ++s, ++t;
    return *s - *t;
}

int str_cmp2(const char *s, const char *t)
{
	int  i;
    for (i = 0; s[i] == t[i] && s[i] != '\0'; ++i)
        ;
	return s[i] - t[i];
}

Почему сlang оптимизировал второй вариант лучше?
Посмотреть данный пример (Compiler Explorer):
  • Вопрос задан
  • 163 просмотра
Пригласить эксперта
Ответы на вопрос 3
@Mercury13
Программист на «си с крестами» и не только
Интересно тут другое. Компилятор первую версию превращает во вторую — базово-индексная адресация очень быстра, а дважды прибавлять единицу — не лучший вариант. К тому же он обнаруживает параллельные циклы и устраивает им одинаковый индекс.

Кстати, посмотри интереса ради gcc -Os.
Ответ написан
@res2001
Developer, ex-admin
В первом случае первая итерация цикла выполняется вне цикла (отсюда и больше размер). Во втором варианте все итерации выполняются в цикле.
Код внутри цикла один и тот же. Скорость исполнения будет одинакова.
Разница только в том, что первый вариант на несколько байт больше размером.
Кстати, gcc показывает идентичный код в обоих случаях.

Предлагаю еще такой вариант:
int str_cmp1(const char *s, const char *t)
{
 while (*s == *t++ && *s != '\0')  ++s;
    return *s - *t;
}
Ответ написан
@potan
Компилятор не может понять, что переменные с указателем больше ни где не используются (например, что одна из них не указывает на вторую) и поддерживает их актуальное значение, что мешает оптимизации.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы