Самый быстрый способ выполнить непроверенное сложение целых чисел в VB.Net?

StackOverflow https://stackoverflow.com/questions/2403154

  •  18-09-2019
  •  | 
  •  

Вопрос

У меня есть проект, в котором я хочу проверять арифметику по умолчанию, за исключением одного места, чувствительного к производительности.К сожалению, в VB.Net нет «непроверенного» блока.

В идеале фреймворк должен иметь какой-то целочисленный тип с явно непроверяемой арифметикой, но я не нашел ничего подобного.Я обнаружил, что в деревьях выражений есть двоичные выражения для непроверяемых операций, но накладные расходы на делегирование сводят на нет непроверяемое преимущество (и даже больше).

В настоящее время я конвертирую входные данные в UInt64/Int64 перед выполнением арифметических операций, а затем конвертирую обратно (с поразрядным оператором And, чтобы обеспечить попадание в диапазон).Это примерно на 50% медленнее, чем непроверяемая арифметика (согласно профилированию).

Перемещение чувствительной к арифметике части в проект с непроверенной арифметикой может сработать, но кажется излишним отдавать ей сборку целиком.

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

Решение

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

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

Я знаю, что это устарело, но недавно мне нужно было преобразовать некоторый код C#, который использовался без проверки, и я решил поделиться, как я это сделал.Это чистый код VB, и его можно использовать по своему усмотрению (а не для всего проекта).

Хитрость заключается в том, чтобы создать структуру, содержащую длинное поле и два целочисленных поля.Затем используйте атрибуты StructLayout и FieldOffset, чтобы создать объединение длинного и двух целых чисел.Поля могут (должны) быть закрытыми.Используйте расширяющие операторы CType для преобразования Long в структуру и из структуры в Integer (с использованием нижнего целочисленного значения).Добавьте перегруженные операторы для +, -, * и т. д.и престо!непроверенная арифметика в VB!

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

Вот пример:

<StructLayout(LayoutKind.Explicit)>
Public Structure UncheckedInteger

    <FieldOffset(0)>
    Private longValue As Long
    <FieldOffset(0)>
    Private intValueLo As Integer
    <FieldOffset(4)>
    Private intValueHi As Integer

    Private Sub New(newLongValue As Long)
        longValue = newLongValue
    End Sub

    Public Overloads Shared Widening Operator CType(value As Long) As UncheckedInteger
        Return New UncheckedInteger(value)
    End Operator

    Public Overloads Shared Widening Operator CType(value As UncheckedInteger) As Long
        Return value.longValue
    End Operator

    Public Overloads Shared Widening Operator CType(value As UncheckedInteger) As Integer
        Return value.intValueLo
    End Operator

    Public Overloads Shared Operator *(x As UncheckedInteger, y As Integer) As UncheckedInteger
        Return New UncheckedInteger(x.longValue * y)
    End Operator

    Public Overloads Shared Operator Xor(x As UncheckedInteger, y As Integer) As UncheckedInteger
        Return New UncheckedInteger(x.longValue Xor y)
    End Operator

    ' Any other operator overload you need...
End Structure

Используйте структуру в коде следующим образом:

Dim x As UncheckedInteger = 2147483647
Dim result As Integer = x * 2  ' This would throw OverflowException using just Integers

Console.WriteLine(result.ToString())  ' -2

Будьте осторожны, чтобы ваши вычисления не переполнились, прежде чем присваивать результат UncheckedInteger.Вы можете создать структуры UncheckedShort и UncheckedByte, используя ту же технику.

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