Экономит ли возвращаемый тип пространство или время? - PullRequest
0 голосов
/ 05 апреля 2019

Имеет ли значение тип возвращаемого значения при возврате из функции?

Это вопрос из двух частей.Я считаю, что 8-битная операция будет такой же, как 32-битная операция.Я считаю, что 8-разрядное значение используется в 32-разрядном регистре, поэтому оно будет преобразовано в 32-разрядное значение.Затем он будет приведен к 8-битному значению.

unsigned char SomeFunc()   <- Quickest and less memory.
unsigned short SomeFunc()
unsigned long SomeFunc()

"Все операции должны выполняться с наименьшей переменной везде, где это возможно, это экономит время и пространство" True или False?

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

Я понимаю, что может возникнуть необходимость вернуть символ / байт, если это все, с чем вы имеете дело, но вы все равно можете вернуть длинный и разыграть его.Я думаю, что вы продолжаете кастинг в любом случае, будь то до или после выхода из функции.Я почти думаю, что легче и быстрее иметь дело с 32-битными значениями, чем с 16 или 8-битными.

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

unsigned long SomeFunc(unsigned char a, unsigned char b);
{
  unsigned long c = a + b;
  return c;
}

или

unsigned long SomeFunc(unsigned char a);
{
  //This will be promoted to a 32-bit value anyways.
  return a & 0x1;
}

Следующая функция как-то будет быстрее и займет меньше памяти?

unsigned char SomeFunc(unsigned char a);
{
  //This will be promoted to a 32-bit value anyways.
  return a & 0x1;
}

1 Ответ

0 голосов
/ 05 апреля 2019

tl; dr: Доверяйте своему оптимизатору.Не боритесь с системой типов.


Да, вы должны использовать наименьший тип.

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

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

Не всепамять - это одна переменнаяРассмотрим массивы и структуры.Они размещены в больших блоках за пределами 32- или 64-битных собственных размеров.Если вы возвращаете больший тип, чем необходимо, вы заставляете массив или структуру, хранящие его, использовать больше памяти.Например, если вы возвращаете int, где вы должны возвращать char, и мне нужно сохранить эти значения в массиве, этот массив будет в 4-8 раз больше.

Я понимаю, что может возникнуть необходимость вернуть символ / байт, если это все, с чем вы имеете дело, но вы все равно можете вернуть длинный и разыграть его.Я думаю, что вы продолжаете кастинг в любом случае, будь то до или после выхода из функции.Я почти думаю, что проще и быстрее иметь дело с 32-битными значениями, чем с 16 или 8-битными значениями.

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

Бесплатное литье наносит ущерб безопасности системы типов.Проверка типов позволяет узнать, помещаете ли вы данные неправильного типа или размера в неправильное место.Кастинг говорит компилятору: «Я знаю, что это выглядит неправильно, но поверь мне, я знаю, что я делаю».Это следует делать только при необходимости.Если вы безвозмездно преобразуетесь, вы теряете эту помощь от компилятора.Если вы допустите ошибку, компилятор не сможет вам помочь.

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


Что касается unsigned long против unsigned char, то при компиляции двух функций с помощью clang -O3 -S и разборе сборки обнаруживается небольшая разница:

-   movq    %rdi, %rax
+   movl    %edi, %eax

Реализация unsigned char будет использовать 32-битный регистр, в то время как unsigned long будет использовать 64-битный регистр.Имеет ли это значение?Не знаю, наверное нет.Определенно недостаточно для победы над системой типов.

...