Подтвердить что ты не робот

Почему я должен использовать int вместо байта или short в С#

Я нашел несколько потоков в связи с этой проблемой. Большинство людей предпочитают использовать int в своем коде С# на борту, даже если байт или smallint будут обрабатывать данные, если это не мобильное приложение. Я не понимаю, почему. Разве не имеет смысла определять ваш тип данных С# как тот же тип данных, который был бы в вашем решении для хранения данных?

Мое помещение: Если я использую типизированный набор данных, классы Linq2SQL, POCO, так или иначе, я буду сталкиваться с проблемами преобразования типов данных компилятора, если я не буду синхронизировать свои типы данных по моим уровням. Мне не очень нравится делать System.Convert все время только потому, что было проще использовать int через плату в коде С#. Я всегда использовал любой наименьший тип данных, необходимый для обработки данных в базе данных, а также в коде, чтобы мой интерфейс к базе данных был чистым. Поэтому я бы поставил, что 75% моего кода на С# использует байты или короткие, а не int, потому что это то, что находится в базе данных.

Возможности: Означает ли это, что большинство людей, которые просто используют int для всего кода, также используют тип данных int для своих типов данных sql-хранилища и могут меньше заботиться об общем размере своей базы данных или же они делают system.convert в коде везде, где это применимо?

Почему мне все равно: я работал навсегда, и я просто хочу быть в курсе лучших практик и стандартных соглашений о кодировании.

4b9b3361

Ответ 1

По производительности, во всех случаях int быстрее. ЦП предназначен для эффективной работы с 32-битными значениями.

Более короткие значения сложны для решения. Чтобы прочитать один байт, скажем, CPU должен прочитать 32-битный блок, который содержит его, а затем замаскировать верхние 24 бита.

Чтобы записать байт, он должен прочитать 32-битный блок назначения, перезаписать младшие 8 бит с требуемым значением байта и снова записать весь 32-битный блок.

Космически, конечно, вы сохраняете несколько байтов, используя меньшие типы данных. Поэтому, если вы создаете таблицу с несколькими миллионами строк, то более короткие типы данных могут быть рассмотрены. (И то же самое может быть хорошей причиной, почему вы должны использовать более мелкие типы данных в своей базе данных)

И корректность, int не легко переполняется. Что, если вы думаете, что ваша ценность будет соответствовать байту, а затем в какой-то момент в будущем некоторые безобидные изменения кода означают, что в него хранятся более крупные значения?

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

Ответ 2

Я опоздал всего на 6 лет, но, возможно, я смогу помочь кому-то еще.

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

  • Если есть вероятность, что данные не будут соответствовать в будущем, используйте больший тип int.
  • Если переменная используется в качестве поля struct/class, то по умолчанию она будет заполнена, чтобы в любом случае занять все 32-битные значения, поэтому использование byte/int16 не сэкономит память.
  • Если переменная недолговечна (как внутри функции), то меньшие типы данных мало чем помогут.
  • "byte" или "char" иногда могут лучше описывать данные и могут выполнять проверку времени компиляции, чтобы убедиться, что большие значения не были назначены ему случайно. Например, если сохранить день месяца (1-31) с помощью байта и попытаться присвоить ему 1000, то это вызовет ошибку.
  • Если переменная используется в массиве примерно 100 или более, я бы использовал меньший тип данных, если это имеет смысл.
  • Массивы byte и int16 не так поточно-безопасны, как int (примитив).

Одна тема, которую никто не затронул, - это ограниченный кеш процессора. Меньшие программы выполняются быстрее, чем большие, потому что процессор может вместить большую часть программы в более быстрых кэшах L1/L2/L3.

Использование типа int может привести к меньшему количеству инструкций ЦП, однако это также приведет к тому, что более высокий процент памяти данных не поместится в кэш ЦП. Инструкции дешевы для исполнения. Современные процессорные ядра могут выполнять 3-7 инструкций за такт, однако, с одной стороны, один промах кэша может стоить 1000-2000 тактов, поскольку он должен идти до оперативной памяти.

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

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

const int SIZE = 10000000, LOOPS = 80000;
byte[] array = Enumerable.Repeat(0, SIZE).Select(i => (byte)r.Next(10)).ToArray();
int[] visitOrder = Enumerable.Repeat(0, LOOPS).Select(i => r.Next(SIZE)).ToArray();

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int sum = 0;
foreach (int v in visitOrder)
    sum += array[v];
sw.Stop();

Вот результаты во времени (тики): (x86, режим выпуска, без отладчика,.NET 4.5, I7-3930k) (чем меньше, тем лучше)

________________ Array Size __________________
       10  100   1K   10K  100K    1M   10M 
byte: 549  559  552   552   568   632  3041  
int : 549  566  552   562   590  1803  4206
  • случайный доступ к 1M элементов с использованием байта на моем процессоре увеличил производительность на 285%!
  • Что-нибудь под 10000 было едва заметно.
  • int никогда не был быстрее байта для этого базового теста суммы.
  • Эти значения будут различаться для разных процессоров с разными размерами кэша.

Последнее замечание: иногда я смотрю на платформу .NET с открытым исходным кодом, чтобы узнать, что делают эксперты Microsoft. .NET Framework использует byte/int16 на удивление мало. Я не мог найти на самом деле.

Ответ 3

Вам придется иметь дело с несколькими рядами BILLION, прежде чем это будет иметь существенное различие в объемах хранения. Допустим, что у вас есть три столбца, и вместо использования байтового эквивалентного типа базы данных вы используете int-эквивалент.

Это дает нам 3 (столбцы) x 3 (байты дополнительно) для каждой строки или 9 байт в строке.

Это означает, что для "нескольких миллионов строк" ​​(скажем, три миллиона) вы потребляете всего 27 мегабайт дискового пространства! К счастью, поскольку мы больше не живем в 1970-х годах, вам не стоит беспокоиться об этом:)

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

Ответ 4

По большей части, "Нет".

Если вы не знаете заранее, что будете иметь дело со 100 миллионами строк, это микро-оптимизация.

Сделайте то, что лучше подходит для модели домена. Позже, если у вас есть проблемы с производительностью, контрольная точка и профиль, чтобы указать, где они происходят.

Ответ 5

Не то, чтобы я не верил Jon Grant и другим, но я должен был сам убедиться в нашем "миллионном столе". Стол имеет 1 018 000. Я преобразовал 11 строк tinyint и 6 маленьких столбцов в int, было уже 5 int и 3 smalldatetimes. 4 разных индекса использовали комбинацию различных типов данных, но, очевидно, новые индексы теперь все используют столбцы int.

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

Таким образом, 30 мб стоит того, чтобы использовать все разные типы данных, No Way! Я уезжаю в страну INT, спасибо всем за то, что вы заставляете этого анального ретентивного программиста вернуться к счастливой счастливой жизни, не превышающей целых конверсий... yippeee!

Ответ 6

Если int используется повсюду, не требуются кастинг или преобразования. Это больший удар для доллара, чем память, которую вы сохраните, используя несколько целых размеров.

Это просто упрощает жизнь.

Ответ 7

Время выполнения .NET оптимизировано для Int32. См. Предыдущее обсуждение в .NET Integer vs Int16?