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

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

سؤال

متعلق ب هذا السؤال, ، بناء على تعليق المستخدم اريك ليبيرت.

هل هناك أي سيناريو حيث حبل هيكل البيانات أكثر كفاءة من باني سلسلة؟ إنه رأي بعض الناس أن هياكل بيانات الحبل لا تكون بشكل أفضل تقريبا من حيث السرعة من السلسلة الأصلية أو عمليات منشئ السلسلة في الحالات النموذجية، لذلك أنا فضولي لرؤية سيناريوهات واقعية حيث يكون الحبال بالفعل أفضل.

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

المحلول

الوثائق ل التنفيذ SGI C ++ يذهب إلى بعض التفاصيل على السلوكيات الكبيرة الآية آيات العوامل المستمرة التي هي مفيدة.

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

إيجابيات كبيرة:

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

سلبيات كبيرة:

  • تصبح الوصول العشوائي للقراءة س (سجل n)
  • يبدو أن العوامل المستمرة على وصول القراءة المتسلسل بين 5 و 10
  • الاستخدام الفعال ل API يستوجب يعامله كحبل، وليس فقط إسقاط حبل كتنفيذ دعم على واجهة برمجة تطبيقات "عادية".

هذا يؤدي إلى عدد قليل من الاستخدامات "الواضحة" (المذكورة الأولى صراحة من قبل SGI).

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

هناك حالات يمكن فيها نقل سلوك المجال الخاص بالسلسلة بالتعويضات البسيطة نسبيا على تنفيذ الحبل للسماح:

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

كما ترون من الأمثلة المدرجة، كل ما يسقط جيدا في فئة "Niche". علاوة على ذلك، قد يكون هناك عدة بدائل متفوقة إذا كنت على استعداد / قادرة على إعادة كتابة الخوارزمية كعملية معالجة دفق بدلا من ذلك.

نصائح أخرى

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

(من وجهة نظر C #)

هيكل بيانات الحبل كشجرة ثنائية أفضل في بعض المواقف. عندما تنظر إلى قيم سلسلة كبيرة للغاية (فكر في 100+ ميغابايت من XML من SQL)، يمكن أن تحافظ بنية بيانات الحبل على العملية بأكملها خارج كومة الكائنات الكبرى الكبيرة، حيث يضرب كائن السلسلة عندما يمر 85000 بايت.

إذا كنت تبحث في سلاسل من 5 إلى 1000 حرفا، فمن المحتمل أن لا يحسن الأداء بما يكفي لتكون يستحق كل هذا العناء. هذه حالة أخرى من بنية بيانات مصممة ل 5٪ من الأشخاص الذين لديهم موقف متطرف.

ال مسابقة برمجة ICFP العاشرة اعتمد, ، أساسا، على الأشخاص الذين يستخدمون هيكل بيانات الحبل لحل فعال. كانت هذه خدعة كبيرة للحصول على VM ركض في وقت معقول.

الحبل ممتاز إذا كان هناك الكثير من البادئة (على ما يبدو كلمة "الإضراب" يتكون من قبل الناس وليس كلمة واحدة مناسبة!) ويحتمل أن تكون أفضل للإدراج؛ يستخدم StringBuilders الذاكرة المستمرة، لذلك يعمل فقط بكفاءة لإلحاق.

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

الحبال رائعة لتحرير المخازن المؤقتة، على سبيل المثال بنية البيانات وراءها، قول Textarea قوة المؤسسة. لذلك (استرخاء من الحبال، مثل قائمة خطوط مرتبطة بدلا من شجرة ثنائية) شائعة جدا في عالم التحكم في العالم، ولكن هذا ليس يتعرض للمطورين ومستخدمي تلك الضوابط.

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

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

عموما، تم تحسين Stransbuilder لإلحاق وحاول تقليل إجمالي عدد إعادة التدوين دون أن يتم الإعلان عن الكثير. الضمان النموذجي هو (مخصصات Log2 N، وأقل من 2.5x الذاكرة). عادة ما تم بناء السلسلة مرة واحدة ويمكن استخدامها بعد ذلك منذ فترة طويلة دون تعديلها.

تم تحسين الحبل للإدراجات والتطفل المتكرر، وتحاول التقليل من ذلك كمية البيانات المنسوخة (بموجب عدد أكبر من المخصصات). في تطبيق المخزن المؤقت الخطي، يصبح كل إدراج وحذف س (ن)، وعادة ما عليك أن تمثل إدراج حرف واحد.

غالبا ما تستخدم JavaScript VMS الحبال للحصول على سلاسل.

Maxime Chevalier-Boisvert، مطور Higgs JavaScript VM، يقول:

في JavaScript، يمكنك استخدام صفائف من الأوتار، وفي نهاية المطاف صفيف .Protype.join لجعل سلسلة سلسلة سريعة بشكل معقول، س (N)، ولكن "الطبيعية"، ولكن "الطبيعية"، ولكن المبرمجين "الطبيعي" يميلون إلى بناء السلاسل هو إلحاق فقط باستخدام المشغل + = بناء تدريجيا لهم. جيهs سلاسل غير قابلة للتغيير، لذلك إذا لم يكن هذا غير محسن داخليا، فإن الإلحاق الإضافي هو O (N2). أعتقد أنه من المحتمل أن يتم تنفيذ الحبال في محركات JS على وجه التحديد بسبب معايير Sunspider التي تقوم بتلويها السلسلة. استخدم مسفخو محركات JS الحبال للحصول على حافة على الآخرين من خلال صنع شيء بطيئ سابقا بشكل أسرع. إذا لم يكن الأمر كذلك بالنسبة لتلك المعايير، فأعتقد أن يبكي من المجتمع حول سلسلة الإدلاء بإلحاق الأداء بشكل سيئ ربما يكون قد تم الوفاء ب "استخدام صفيف .protoType.join، Dummy!".

أيضا.

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