.NET Integer против Int16?

У меня сомнительная практика программирования.

Когда мне нужно перебрать небольшой список элементов, предел количества которых меньше 32000, я использую Int16 для своего типа переменной я вместо Integer. Я делаю это потому, что считаю, что использование Int16 более эффективно, чем полноценный Integer.

Я ошибаюсь? Нет ли эффективной разницы в производительности между использованием Int16 и Integer? Должен ли я прекратить использовать Int16 и просто придерживаться Integer для всех моих потребностей в подсчете / итерациях?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
52
0
23 441
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Верно и обратное.

32 (или 64) битные целые числа быстрее, чем int16. В общем, родной тип данных самый быстрый.

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

На самом деле Int16 может быть эффективным меньше, потому что инструкции x86 для доступа к словам занимают больше места, чем инструкции для доступа к двойным словам. Это будет зависеть от того, что делает JIT. Но несмотря ни на что, он почти наверняка не эффективен при использовании более в качестве переменной в итерации.

Никогда не предполагайте эффективности.

Что является более эффективным, а что нет, будет варьироваться от компилятора к компилятору и от платформы к платформе. Если вы на самом деле не проверили это, невозможно определить, является ли int16 или int более эффективным.

Я бы просто придерживался ints, если вы не столкнетесь с доказанной проблемой производительности, связанной с исправлениями int16.

Он просит .net, поэтому платформа очень хорошо определена.

Nils Pipenbrinck 24.09.2008 22:51

Я не могу представить себе существенного прироста производительности Int16 по сравнению с int.

Вы сохраняете некоторые биты в объявлении переменной.

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

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

Это может иметь смысл с точки зрения хранилища, если у вас очень ограниченные ресурсы - встроенные системы с крошечным стеком, проводные протоколы, предназначенные для медленных сетей (например, GPRS и т. д.), И так далее.

Используйте Int32 на 32-битных машинах (или Int64 на 64-битных машинах) для максимальной производительности. Используйте меньший целочисленный тип, если В самом деле беспокоит занимаемое пространство (хотя может быть медленнее).

Нет значительного увеличения производительности при использовании типа данных меньшего, чем Int32, на самом деле, я где-то читал, что использование Int32 будет быстрее, чем Int16 из-за выделения памяти

Вы должны почти всегда использовать Int32 или Int64 (и, нет, вы не получаете кредит, используя UInt32 или UInt64) при циклическом обходе массива или коллекции по индексу.

Наиболее очевидная причина того, что он менее эффективен, заключается в том, что все индексы массивов и коллекций, найденные в BCL, принимают Int32, поэтому неявное приведение всегда произойдет в коде, который пытается использовать Int16 в качестве индекса.

Менее очевидная причина (и причина, по которой массивы принимают Int32 в качестве индекса) заключается в том, что в спецификации CIL указано, что все значения стека операций - это либоInt32 или Int64. Каждый раз, когда вы загружаете или сохраняете значение в любой другой целочисленный тип (Byte, SByte, UInt16, Int16, UInt32 или UInt64), выполняется операция неявного преобразования. Беззнаковые типы не имеют штрафа за загрузку, но для сохранения значения это равносильно усечению и возможной проверке переполнения. Для подписанных типов каждый load sign-extends, и каждый store sign-collaps (и имеет возможную проверку переполнения).

Больше всего от этого вы столкнетесь в самом цикле, а не в доступе к массиву. Например, возьмите этот невинно выглядящий цикл:

for (short i = 0; i < 32000; i++) {
    ...
}

Выглядит хорошо, правда? Неа! Вы можете в основном игнорировать инициализацию (short i = 0), поскольку она происходит только один раз, но части сравнения (i<32000) и увеличения (i++) происходят 32000 раз. Вот небольшой псевдокод того, как эта штука выглядит на машинном уровне:

  Int16 i = 0;
LOOP:
  Int32 temp0 = Convert_I16_To_I32(i); // !!!
  if (temp0 >= 32000) goto END;
  ...
  Int32 temp1 = Convert_I16_To_I32(i); // !!!
  Int32 temp2 = temp1 + 1;
  i = Convert_I32_To_I16(temp2); // !!!
  goto LOOP;
END:

Там есть преобразования 3, которые выполняются 32000 раз. И их можно было полностью избежать, просто используя Int32 или Int64.

Обновление: как я сказал в комментарии, теперь я фактически написал сообщение в блоге по этой теме, Интегральные типы данных .NET и вы

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

Alex Lyman 02.10.2008 21:26
Ответ принят как подходящий

Согласно приведенной ниже ссылке, время выполнения оптимизирует производительность Int32 и рекомендует их для счетчиков и других часто используемых операций.

Из книги: Комплект для самостоятельного обучения MCTS (экзамен 70-536): Microsoft® .NET Framework 2.0 - Application Development Foundation

Глава 1: «Основы Framework»
Урок 1: «Использование типов значений»

Best Practices: Optimizing performance with built-in types

The runtime optimizes the performance of 32-bit integer types (Int32 and UInt32), so use those types for counters and other frequently accessed integral variables.

For floating-point operations, Double is the most efficient type because those operations are optimized by hardware.

Кроме того, в Таблице 1-1 того же раздела перечислены рекомендуемые применения для каждого типа. Имеет отношение к этому обсуждению:

  • Int16 - взаимодействие и другое специализированное использование
  • Int32 - Целые числа и счетчики
  • Int64 - большие целые числа

Остальные здесь верны, используйте только меньше, чем Int32 (для 32-битного кода) / Int64 (для 64-битного кода), если он вам нужен для экстремальных требований к хранилищу или для другого уровня применения в поле бизнес-объекта (вы все равно должны иметь в этом случае, конечно, проверку на надлежащий уровень).

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

Но хороший вопрос. Вы узнаете больше о том, как это делает компилятор. Если вы хотите научиться программировать более эффективно, изучение основ IL и того, как компиляторы C# / VB выполняют свою работу, было бы отличной идеей.

Другие вопросы по теме