أسرع طريقة للقيام بإضافة عدد صحيح غير محدد في VB.NET؟

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

  •  18-09-2019
  •  | 
  •  

سؤال

لدي مشروع أرغب فيه في فحص الحساب افتراضيا، باستثناء بقعة حساسة لأداء الأداء. لسوء الحظ، ليس لدى VB.NET كتلة "غير مرفوعة".

من الناحية المثالية، سيكون للإطار نوعا من نوع عدد صحيح باسم حسابي غير محدد بشكل صريح، لكنني لم أجد أي شيء من هذا القبيل. لقد وجدت أن أشجار التعبير تحتوي على تعبيرات ثنائية لعمليات غير محددة، لكن المندوب العلوي يلغي الميزة التي لم يتم التحقق منها (ثم بعضها).

حاليا أقوم بتحويل المدخلات إلى UINT64 / INT64 قبل القيام بالحساب، ثم تحويل الظهر (مع Bitwise وضمان التشغيل). انها حوالي 50٪ أبطأ من الحساب الذي لم يتم التحقق منه (حسب التنميط).

نقل الجزء الحساسة للحساب إلى مشروع مع حساب حسابي غير محدد قد يعمل، ولكن يبدو وكأنه مبالغ فيه لإعطائها تجميعا في حد ذاته.

هل كانت مفيدة؟

المحلول

شخصيا، أعتقد أن ترك هذا في التجمعات الخاصة به، خاصة وأنه سيكون مثل هذه التجميع الصغيرة، هو خيار جيد. هذا يجعل الصيانة أسهل، لأنه من السهل تجديد هذه الجمعية في أي وقت. فقط قم بإعلام التجميع المنفصل دون تحديد، ووضع رمز حساس في الأداء هناك.

نصائح أخرى

أعلم أن هذا قديم، لكنني كنت بحاجة مؤخرا لتحويل بعض الكود C # الذي استخدم دون رادع وأعتقد أنني سأشارك كيف فعلت ذلك. إنه رمز VB النقي ويمكن تحريره ولكنك تحتاج (بدلا من خيار على مستوى المشروع).

الحيلة هي إنشاء بنية تحتوي على حقل طويل وحقول عدد صحيح. ثم استخدم سمات Instructlayout وسمات الحضور لإنشاء نقابة من الأطباء الطويلين. يمكن أن تكون الحقول (يجب) خاصة. استخدم تشغيل مشغلي CTTYPE لتوسيع نطاقها من الهيكل لفترة طويلة ومن هيكل عدد صحيح (باستخدام قيمة عدد صحيح منخفض). إضافة المشغل الزائد ل +، -، *، الخ ... و presto! حسابي غير محدد في VB!

نوع من ... سوف لا تزال تتجاوز، كما أشار ستريلانك، إذا كانت القيمة الطويلة تدخل خارج النطاق للأسنان. لكنه يعمل بشكل جيد للغاية بالنسبة للكثير من المواقف التي يتم فيها استخدامها.

إليك مثال:

<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

حذرا أن الحسابات الخاصة بك لا تفيض قبل تعيين النتيجة إلى UnchemnedItnger. يمكنك إنشاء هياكل Uncheckledshort وإلغاء تحديدها باستخدام نفس التقنية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top