Double.tryparse أو تحويل. TodoDouble - وهو أسرع وأكثر أمانا؟

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

  •  06-09-2019
  •  | 
  •  

سؤال

يقرأ طلبي ملف Excel باستخدام VSTO وأضيف بيانات القراءة إلى StringDictionary. وبعد إنه يضيف فقط البيانات التي هي أرقام مع عدد قليل من الأرقام (1000 1000،2 1000،34 - فاصلة محدد في المعايير الروسية).

ما هو الأفضل للتحقق مما إذا كانت السلسلة الحالية رقم مناسب؟

object data, string key; // data had read

try
{
  Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
  dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
  // is not a number
}

أو

double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
  dic.Add(key, str);
}

لدي لاستخدام StringDictionary بدلا من Dictionary<string, double> بسبب مشاكل خوارزمية التحليل التالية.

أسئلتي: ما هي الطريقة أسرع؟ ما هو أكثر أمانا؟

وهل من الأفضل الاتصال Convert.ToDouble(object) أو Convert.ToDouble(string) ?

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

المحلول

فعلت اختبار سريع غير علمي في وضع الإصدار. لقد استخدمت مدخلتان: "2.34523" و "badinput" في كلتا الأولين ومدرسة 1،000،000 مرة.

إدخال صالح:

Double.TryParse = 646ms
Convert.ToDouble = 662 ms

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

مدخل غير صالح:

Double.TryParse = 612ms
Convert.ToDouble = ..

حسنا .. كان يعمل لفترة طويلة. أعيد اراد كل شيء باستخدام 1000 تكرار و Convert.ToDouble مع الإدخال السيئ استغرق 8.3 ثانية. في المتوسط، سيستغرق الأمر أكثر من ساعتين. لا يهمني كيف يكون الاختبار الأساسي، في حالة الإدخال غير صالح، Convert.ToDoubleسيؤدي زيادة الاستثناء إلى أن يدمر أدائك.

لذلك، إليك صوت آخر ل TryParse مع بعض الأرقام لدعمها.

نصائح أخرى

لتبدأ، كنت أستخدم double.Parse بدلا من Convert.ToDouble في المقام الأول.

حول ما إذا كان يجب عليك استخدام Parse أو TryParse: يمكنك المتابعة إذا كان هناك بيانات إدخال سيئة، أم أن حالة استثنائية حقا؟ إذا كان استثنائيا، استخدم Parse ودعها تفجير إذا كانت المدخلات سيئة. إذا كان متوقعا ويمكن التعامل معها نظيفة TryParse.

إرشادات تصميم .NET Framework تنصح باستخدام طرق TRY. تجنب الاستثناءات عادة ما تكون فكرة جيدة.

Convert.ToDouble(object) سوف تفعل ((IConvertible) object).ToDouble(null);

والتي سوف تتصل Convert.ToDouble(string, null)

لذلك هو أسرع لاستدعاء نسخة السلسلة.

ومع ذلك، فإن إصدار السلسلة لا يفعل ذلك:

if (value == null)
{
    return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);

لذلك هو أسرع للقيام double.Parse مباشرة.

إذا كنت لن يتم التعامل مع الاستثناء، فهو TryPare. TryParse أسرع لأنه لا يتعين عليه التعامل مع تتبع مكدس الاستثناء بأكمله.

أحاول عموما تجنب Convert فئة (معنى: أنا لا أستخدمه) لأنني أجدها مربكة للغاية: يعطي الكود عددا قليلا جدا من التلميحات حول ما يحدث بالضبط هنا منذ ذلك الحين Convert يسمح بالكثير من التحويلات المختلفة الدلوية تحدث مع نفس الرمز. هذا يجعل من الصعب التحكم في مبرمج ما يحدث بالضبط.

لذلك، فإن نصيحتي ليست أبدا لاستخدام هذه الفئة. ليس من الضروري حقا أيضا (باستثناء التنسيق الثنائي للرقم، لأن العادي ToString طريقة الطبقات الأرقامية لا تقدم طريقة مناسبة للقيام بذلك).

ما لم تكن معينة 100٪ من المدخلات الخاصة بك، والذي نادرا ما يكون الحال، يجب عليك استخدام Double.tryParse.

Convert.ToDouble will throw an exception on non-numbers
Double.Parse will throw an exception on non-numbers or null
Double.TryParse will return false or 0 on any of the above without generating an exception.

تصبح سرعة التحليل ثانوية عند رمي استثناء لأنه ليس هناك أبطأ بكثير من استثناء.

الكثير من الكراهية لتحويل فئة هنا ... فقط لتحقيق التوازن قليلا، هناك ميزة واحدة للتحويل - إذا كنت تسلم كائنا،

Convert.ToDouble(o);

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

باستخدام Double.Parse أو Double.tryparse رائع إذا كان لديك بالفعل في سلسلة، ولكن

Double.Parse(o.ToString());

عليه الذهاب صنع تتغير السلسلة أولا واعتمادا على مدخلاتك التي يمكن أن تكون أكثر تكلفة.

Double.tryparse IMO.

من الأسهل بالنسبة لك التعامل معها، ستعرف بالضبط حيث حدث الخطأ.

ثم يمكنك التعامل معها كيف ترى مناسبا إذا ترجع FALSE (IE لا يمكن تحويل).

أنا دائما المفضل باستخدام TryParse() الأساليب لأنها ستؤدي إلى تبديل النجاح أو الفشل في التحويل دون الحاجة إلى القلق بشأن الاستثناءات.

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

كنت أتوقع TryParse أن تكون أسرع أيضا، لأنه يتجنب النفقات العامة للتعامل مع الاستثناء. ولكن استخدام أداة مرجعية، مثل ميني باي جون سكيت لمقارنة الاحتمالات المختلفة.

هذا سؤال قديم مثير للاهتمام. أضيف إجابة لأن لا أحد لاحظ بضعة أشياء بالسؤال الأصلي.

وهو أسرع: تحويل.todouble أو double.tryparse؟ ما هو أكثر أمانا: convert.todouble أو double.tryparse؟

سأجيب على حد سواء هذه الأسئلة (سأقوم بتحديث الإجابة لاحقا)، بالتفصيل، ولكن أولا:

للسلامة، الشيء كل مخرج مبرمج في هذا السؤال هو الخط (التركيز لي):

يضيف فقط البيانات التي هي أرقام مع بضع أرقام (1000 1000،2 1000،34 - فاصلة هو محدد بالمعايير الروسية).

تليها هذا الرمز مثال:

Convert.ToDouble(regionData, CultureInfo.CurrentCulture);

ما هو مثير للاهتمام هنا هو أنه إذا كانت جداول البيانات بتنسيق الأرقام الروسية، فلن تكتب Excel بشكل صحيح حقول الخلية، فما هو التفسير الصحيح للقيم الواردة من Excel؟

فيما يلي شيء آخر مثير للاهتمام حول المثالين، فيما يتعلق بالسرعة:

catch (InvalidCastException)
{
    // is not a number
}

من المحتمل أن يولد MSIL الذي يشبه هذا:

catch [mscorlib]System.InvalidCastException 
{
  IL_0023:  stloc.0
  IL_0024:  nop
  IL_0025:  ldloc.0
  IL_0026:  nop
  IL_002b:  nop
  IL_002c:  nop
  IL_002d:  leave.s    IL_002f
}  // end handler
IL_002f: nop
IL_0030: return

وبهذا المعنى، يمكننا أن نقارن إجمالي عدد تعليمات MSIL التي أجريتها كل برنامج - أكثر في ذلك لاحقا أثناء تحديث هذا المنصب.

أعتقد أن التعليمات البرمجية يجب أن تكون صحيحة وواضحة وسريعة ... في هذا الترتيب!

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