Domanda

Ho un progetto in cui voglio avere controllato l'aritmetica per impostazione predefinita, ad eccezione di un punto sensibile delle prestazioni. Purtroppo, VB.Net non ha un blocco 'incontrollata'.

Idealmente, il quadro dovrebbe avere una sorta di tipo intero con l'aritmetica esplicitamente incontrollato, ma non ho trovato niente di simile. Ho trovato che gli alberi di espressione hanno espressioni binarie per le operazioni non controllate, ma l'overhead delegato annulla il vantaggio incontrollata (e poi alcuni).

Attualmente sto convertendo gli ingressi per UInt64 / Int64 prima di fare l'aritmetica, quindi la conversione di nuovo (con un bit per bit E per garantire in-gamma). Si tratta di circa il 50% più lento di aritmetica incontrollato (in base alla profilazione).

Spostare la parte aritmetica sensibile ad un progetto con l'aritmetica incontrollato potrebbe funzionare, ma sembra eccessivo per dare un assemblaggio tutto per sé.

È stato utile?

Soluzione

Personalmente, penso che lasciare questo nella propria assemblea, soprattutto perché sarà una piccola assemblea tale, è una buona opzione. Questo rende la manutenzione più facile, dal momento che è facile per rigenerare questa assemblea in qualsiasi momento. Basta fare un assembly separato contrassegnato incontrollato, e mettere il codice di prestazioni sensibili lì.

Altri suggerimenti

So che questo è vecchio, ma di recente ho avuto bisogno di convertire un codice C # che ha utilizzato incontrollato e io ho pensato di condividere come ho fatto. E 'puro codice VB e può essere ambito tuttavia è necessario (piuttosto che un'opzione a livello di progetto).

Il trucco è quello di creare una struttura che contiene un campo lungo e due campi di numeri interi. Quindi utilizzare StructLayout e FieldOffset attributi per creare un'unione della lunga e due interi. I campi possono (devono) essere privato. Utilizzare allargamento operatori CType convertire da una lunga alla struttura e dalla struttura di un intero (mediante il basso valore intero). Aggiungi sovraccarichi operatore per +, -, *, ecc ... e presto! l'aritmetica non controllato in VB!

Una specie di ... sarà ancora troppo pieno, come Strilanc ha sottolineato, se il valore a lungo va fuori del campo per long. Ma funziona abbastanza bene per un sacco di situazioni in cui incontrollato viene utilizzato.

Ecco un esempio:

<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

Con la struttura in codice come questo:

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

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

Attenzione che i calcoli non fanno troppo pieno prima di assegnare il risultato a un UncheckedInteger. Si potrebbe creare strutture UncheckedShort e UncheckedByte utilizzando la stessa tecnica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top