modo più veloce per fare un'aggiunta intero non controllato in VB.Net?
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é.
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.