Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Лучшие практики:Оптимизация производительности со встроенными типами

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

Для операций с плавающей запятой тип Double является наиболее эффективным, поскольку эти операции оптимизируются аппаратно.

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

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

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

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

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

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

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

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 и вы

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

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

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

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

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

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

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

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

Я бы просто придерживался целых чисел, если только вы не столкнетесь с доказанной проблемой производительности, которую можно исправить с помощью int16.

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top