Как уже писали другие: это не имеет значения для процессора.Инструкции со знаком и без знака занимают одно и то же время. Некоторые операции в арифметике без знака еще проще выполнить, и для них может потребоваться цикл меньше, чем у варианта со знаком (один из примеров - деление с высокой точностью).
Однако этоэто только половина истории.
C ++ определяет целочисленные переполнения со знаком как неопределенное поведение и целые числа без знака как модуль2.Это предлагает совершенно разные возможности оптимизации, которые приводят к другому коду.
Один пример:
int foo (int a)
{
return a * 1000 / 500;
}
unsigned bar (unsigned a)
{
return a * 1000 / 500;
}
Здесь foo можно оптимизировать так:
int foo (int a)
{
return a * 2;
}
И бар останетсято же самое.
Обратите внимание, что математически эти две функции одинаковы, но они начинают давать разные результаты, если аргумент превышает INT_MAX / 1000.
Поскольку эффект переполнения со знаком не определену компилятора есть возможность просто притвориться, что INT_MAX не существует, когда речь идет об упрощении выражений.Для арифметики без знака это не так, и компилятор должен выдавать код, который выполняет умножение и деление.Это, конечно, медленнее, чем оптимизированный вариант.
Примечание. Большинство компиляторов консервативны в том, что касается таких оптимизаций, и включают их только в том случае, если вы их запрашиваете, поскольку они имеют тенденцию нарушать проверки кода и переполнения.Другие компиляторы, особенно в мире встраиваемых систем и DSP, всегда проводят подобные оптимизации даже на низких уровнях оптимизации.Программисты, которые пишут для таких машин, знают тонкие детали, так что это редко является проблемой.
OTOH мы обсуждали истории, в которых программисты на C / C ++ попадают в эту ловушку более одного раза из-за переполнения стека.