2010-03-08 31 views
8

Tôi có một dự án mà tôi muốn kiểm tra số học theo mặc định, ngoại trừ một điểm nhạy cảm về hiệu suất. Thật không may, VB.Net không có một khối 'không được kiểm soát'.Cách nhanh nhất để thực hiện thêm số nguyên không được kiểm tra trong VB.Net?

Lý tưởng nhất là khung sẽ có một số loại số nguyên với số học không được kiểm tra rõ ràng, nhưng tôi không tìm thấy bất kỳ thứ gì như thế. Tôi đã thấy rằng cây biểu thức có biểu thức nhị phân cho các hoạt động không được kiểm tra, nhưng chi phí đại biểu hủy bỏ lợi thế không được kiểm soát (và sau đó một số).

Hiện tại tôi đang chuyển đổi đầu vào thành UInt64/Int64 trước khi thực hiện số học, sau đó chuyển đổi lại (với bitwise và để đảm bảo trong phạm vi). Đó là khoảng 50% chậm hơn so với số học không được kiểm soát (theo hồ sơ).

Di chuyển phần số học nhạy cảm với một dự án có số học không được kiểm soát có thể hoạt động, nhưng có vẻ như quá mức cần thiết để cung cấp cho nó một bản lắp ráp cho chính nó.

+1

C# lắp ráp thêm cho điều này có thể là quá mức cần thiết, nhưng bạn cũng có thể tạo một mô-đun từ tệp C# (một số tham số dòng lệnh cho trình biên dịch), và sau đó sử dụng ILmerge để hợp nhất nó với cụm VB.NET của bạn. – OregonGhost

Trả lời

2

Cá nhân, tôi nghĩ rằng để lại điều này trong hội đồng của riêng mình, đặc biệt là vì nó sẽ là một hội đồng nhỏ như vậy, là một lựa chọn tốt. Điều này giúp bảo trì dễ dàng hơn, vì dễ dàng tái tạo lắp ráp này bất cứ lúc nào. Chỉ cần tạo một hội đồng riêng biệt được gắn cờ không được kiểm soát và đặt mã nhạy cảm về hiệu suất của bạn ở đó.

+0

Bạn có thể làm số học không được kiểm tra trong VB. Vấn đề là nó là một lựa chọn toàn dự án (trong Advanced Compile Options trong tab Compile). –

+0

@Strilanc: Thậm chí tốt hơn - hãy chỉnh sửa câu trả lời của tôi, sau đó. Tôi chỉ muốn tạo một dự án riêng cho sự hoàn hảo của bạn. mã quan trọng, và tham khảo nó, sau đó. –

+4

Tôi đã làm một cái gì đó hơi khác nhau: Tôi đã viết các loại với số học không được kiểm soát và đặt những người trong hội đồng không được kiểm soát. Bây giờ tôi có ModByte/ModInt16/ModInt32/ModInt64 và hội đồng không được kiểm tra chắc chắn sẽ không từ từ hấp thụ mã. –

3

Tôi biết điều này là cũ, nhưng gần đây tôi cần chuyển đổi một số mã C# được sử dụng không được kiểm soát và tôi nghĩ tôi sẽ chia sẻ cách tôi đã làm. Đó là mã VB thuần túy và có thể được dàn tạp tuy nhiên bạn cần (chứ không phải là một tùy chọn toàn dự án).

Bí quyết là tạo cấu trúc chứa trường Dài và hai trường Số nguyên. Sau đó sử dụng các thuộc tính StructLayout và FieldOffset để tạo một liên kết dài và hai số nguyên. Các trường có thể (nên) là riêng tư. Sử dụng các toán tử CType mở rộng để chuyển đổi từ một Long thành cấu trúc và từ cấu trúc thành một số nguyên (sử dụng giá trị số nguyên thấp). Thêm quá tải toán tử cho +, -, *, v.v. và mau! unithed số học trong VB!

Sắp xếp ... nó sẽ vẫn tràn, như Strilanc đã chỉ ra, nếu giá trị dài vượt ra ngoài phạm vi cho thời gian dài. Nhưng nó hoạt động khá tốt cho rất nhiều tình huống mà bỏ chọn được sử dụng.

Dưới đây là một ví dụ:

<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 

Sử dụng cấu trúc trong mã như thế này:

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

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

cẩn thận rằng tính toán của bạn không tràn trước khi gán kết quả đến một UncheckedInteger. Bạn có thể tạo các cấu trúc UncheckedShort và UncheckedByte bằng cách sử dụng cùng một kỹ thuật.

+0

Điều này sẽ không tràn? Điều gì sẽ xảy ra nếu bạn nhân đôi cho đến khi phạm vi dài cũng bị vượt quá? –

+0

Mã như tôi đã đăng nó chắc chắn sẽ tràn nếu giá trị dài vượt ra ngoài phạm vi của nó. Trong tình huống của tôi, tôi không cần phải lo lắng về điều đó.Nếu tràn giá trị dài là một mối quan tâm, người ta luôn có thể thêm kiểm tra phạm vi. –

Các vấn đề liên quan