문제

하나의 성능에 민감한 지점을 제외하고 기본적으로 산술을 확인하고 싶은 프로젝트가 있습니다. 불행히도 VB.NET에는 '확인되지 않은'블록이 없습니다.

이상적으로 프레임 워크는 명시 적으로 확인되지 않은 산술을 가진 일종의 정수 유형을 가질 것이지만, 그런 것을 찾지 못했습니다. 나는 발현 나무에 검사되지 않은 작업에 대한 이진 표현이 있다는 것을 알았지 만 대의원 오버 헤드는 확인되지 않은 이점 (및 일부)을 취소한다는 것을 알았다.

현재 산술을 수행하기 전에 입력을 uint64/int64로 변환 한 다음 다시 변환 (비트로, 범위 내)을 변환하고 있습니다. 검사되지 않은 산술보다 약 50% 느리게 (프로파일 링에 따르면).

산술에 민감한 부분을 확인하지 않은 산술로 프로젝트로 옮기는 것이 효과가있을 수 있지만, 그 자체로 어셈블리를 제공하는 것은 과잉처럼 보입니다.

도움이 되었습니까?

해결책

개인적으로, 나는 이것을 자체 어셈블리로 남겨 두는 것이 특히 작은 조립이 될 것이기 때문에 좋은 선택이라고 생각합니다. 이는 언제든지이 어셈블리를 쉽게 재생할 수 있기 때문에 유지 보수가 더 쉬워집니다. 별도의 어셈블리를 확인하지 않고 성능에 민감한 코드를 넣으십시오.

다른 팁

나는 이것이 오래되었음을 알고 있지만 최근에 확인되지 않은 C# 코드를 변환해야했으며 어떻게했는지 공유 할 것이라고 생각했습니다. 순수한 VB 코드이며 프로젝트 차원의 옵션이 아니라 필요한 경우 범위를 지정할 수 있습니다.

요령은 긴 필드와 두 개의 정수 필드를 포함하는 구조를 만드는 것입니다. 그런 다음 structlayout 및 fieldoffset 속성을 사용하여 Long과 두 정수의 결합을 만듭니다. 필드는 비공개 일 수 있습니다. 넓은 CTYPE 연산자를 사용하여 오랫동안 구조에서 구조로, 구조에서 정수 (낮은 정수 값을 사용)로 변환하십시오. +, -, *등의 작업자 과부하를 추가하십시오 ... 및 Presto! VB에서 확인되지 않은 산술!

긴 값이 오랫동안 범위를 벗어나면 Strilanc가 지적했듯이 여전히 오버플로됩니다. 그러나 검사되지 않은 많은 상황에서 잘 작동합니다.

예는 다음과 같습니다.

<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

결과를 확인하지 않은 결과를 할당하기 전에 계산이 오버플로되지 않도록주의하십시오. 동일한 기술을 사용하여 확인되지 않은 쇼트 및 확인되지 않은 비료 구조를 만들 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top