في نقطة ما لا باستخدام بـ stringbuilder تصبح تافهة أو النفقات العامة ؟

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

  •  23-08-2019
  •  | 
  •  

سؤال

في الآونة الأخيرة وجدت نفسي باستخدام بـ stringbuilder لجميع سلسلة تسلسالت, الكبيرة والصغيرة, لكن في الآونة الأخيرة أداء الاختبار انا بدلت زميل stringOut = string1 + "." string2 نمط سلسلة (المستخدمة في 10000x + حلقة مع بـ stringbuilder يجري newed في كل مرة) لمدة بـ stringbuilder فقط لرؤية ما الفرق سيكون في ثانوية سلسلة.

وجدت على العديد من أشواط من أداء الاختبار ، التغيير سواء معنويا أعلى أو أقل بغض النظر عن سلسلة أو بـ stringbuilder (إعادة صياغة هذا صغيرة تسلسالت).

في نقطة ما لا 'newing حتى' من الكائن بـ stringbuilder ينفي فوائد استخدام واحد ؟

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

المحلول

القاعدة التي أتابعها هي -

استخدم Stringbuilder عندما يكون عدد التسليط غير معروف في وقت الترجمة.

لذلك، في حالتك، كان كل Strantbuilder إلحاق عدة مرات فقط ثم يتم التخلص منها. هذا ليس حقا نفس شيء مثل

string s = String.Empty;
for (int i = 0; i < 10000; ++i)
{
    s += "A";
}

حيث تستخدم استخدام Stringbuilder تحسين الأداء بشكل كبير لأنك ستخصيص ذاكرة جديدة باستمرار.

نصائح أخرى

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

  • بالتأكيد استخدام StringBuilder عندما كنت وصل في غير تافهة حلقة خاصة إذا كنت لا تعرف تماما (في وقت الترجمة) عدد التكرارات سوف تجعل من خلال الحلقة.على سبيل المثال, قراءة ملف حرف في كل مرة ، بناء سلسلة كما تذهب باستخدام += مشغل يحتمل أن الأداء الانتحار.

  • بالتأكيد استخدام مشغل سلسلة عندما تستطيع (بصورة مقروءة) تحديد كل شيء التي تحتاج إلى أن تكون متصلا في بيان واحد.(إذا كان لديك مجموعة من الأشياء لسلسلة, النظر في الدعوة String.Concat صراحة - أو String.Join إذا كنت بحاجة محدد.)

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

  • إذا كنت في حاجة إلى نتائج المتوسطة من سلسلة لشيء آخر من التغذية التكرار التالي من سلسلة ، StringBuilder لن تساعدك.فعلى سبيل المثال ، إذا كنت بناء الاسم الكامل من الاسم الأول و الاسم الأخير ثم نضيف ثالث قطعة من المعلومات (الاسم المستعار, ربما) إلى النهاية ، سوف تستفيد فقط من استخدام StringBuilder إذا كنت لا تحتاج (الاسم الأول + الاسم الأخير) سلسلة لغرض آخر (كما نفعل في المثال الذي يخلق Person كائن).

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

في بعض الأحيان يستحق النظر إلى توثيق:

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

في مثالك، لا يوجد سوى سلسلة واحدة لكل سلسلة الناتج، لذلك لا تكسب StringBuilder شيئا. يجب عليك استخدام StringBuilder في الحالات التي تضيف فيها نفس السلسلة مرات عديدة، على سبيل المثال:

stringOut = ...
for(...)
    stringOut += "."
    stringOut += string2

حكمي هو بسيط.

  1. إذا كنت تستطيع كتابة تعبير واحد ينتج النهائي، فاستخدم +.
  2. إذا كنت لا تستطيع (بسبب الحجم أو التباين)، فاستخدم StringBuilder.

في تجربتي، تعبيرات مثل:

"Id: " + item.id + " name: " + item.name

يمكن كتابة وفهم بسهولة أكبر بكثير من:

StringBuilder sb = new StringBuilder();
sb.append("Id: ").append(item.id);
sb.append(" name: ").append(item.name);

(متبوعا باستخدام السلسلة من sb حيث كان التعبير المذكور أعلاه قد كتب)، ويؤدي بشكل جيد بنفس القدر (تلميح: انظر إلى التعليمات البرمجية المترجمة لمعرفة لماذا!)

من ناحية أخرى، عندما تكون هناك حاجة إلى تجميع سلسلة بمرور الوقت (نظرا لأن البرنامج يعمل) أو المساحة (تتكون من قيم قادمة من أجزاء مختلفة من التعليمات البرمجية)، بطريقة غير عميلة للكتابة كتعبير واحد ، ثم يتجنب Stransbuilder العلامة العامة (الوقت والذاكرة) من:

String s = somethingExpression;
...
s += someOtherExpression;
...
s += yetAnotherExpression;
...

من MSDN.:

T] فئة سلسلة هو الأفضل لعملية التسليط إذا تم ربط عدد ثابت من كائنات السلسلة. في هذه الحالة، قد يتم دمج عمليات التسليط الفردية في عملية واحدة من قبل المحول البرمجي. كائن Stransbuilder هو الأفضل لعملية التسليط إذا تم تسليم عدد تعسفيا من السلاسل؛ على سبيل المثال، إذا قامت حلقة بتسلسل عدد عشوائي من سلاسل إدخال المستخدم.

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

هناك مقال مثير للاهتمام حول هذا انتهى الترميز الرعب. وبعد حصل جيف النتائج التالية على 100،000 تكرار على ثنائي النواة 3.5 جيجاهرتز Core 2 Duo:

 Simple Concatenation    - 606 ms
 String.Format           - 665 ms
 string.Concat           - 587 ms
 String.Replace          - 979 ms
 StringBuilder           - 588 ms

من دوت صافي بيرل:

متى تستخدم stringbuilder؟

StringBuilder هو التحسين بالكامل، ولا يقدم أي تحسينات منطقية على سلسلة Concat بخلاف تنفيذها الداخلي. ومع ذلك، من الأهمية بمكان استخدامه بشكل صحيح في تطبيقاتك عالية الأداء ومواقع الويب.

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

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