java - first - بدائل أسرع لاستبدال الأسلوب في سلسلة جافا؟




replace first character in string java (6)

حقيقة أن طريقة الاستبدال بإرجاع كائن سلسلة بدلا من استبدال محتويات سلسلة معينة هو أوبتيوس قليلا (ولكن مفهومة عندما كنت تعرف أن السلاسل غير قابل للتغيير في جافا). أنا أخذ ضربة أداء كبيرة باستخدام استبدال متداخلة عميقا في بعض التعليمات البرمجية. هل هناك شيء يمكن أن يحل محله مع ذلك من شأنه أن يجعل من أسرع؟


الوظائف السابقة على حق، سترينغبويلدر / سترينغبوفر هي الحل.

ولكن، لديك أيضا إلى السؤال إذا كان من الجيد أن تفعل استبدال على سلاسل كبيرة في الذاكرة.

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

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


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


هذا هو ما المقصود سترينغبويلدر ل. إذا كنت تريد الذهاب إلى القيام الكثير من التلاعب، تفعل ذلك على StringBuilder ، ثم تحويل ذلك إلى String كلما كنت في حاجة إليها.

ويرد وصف StringBuilder بالتالي:

"تسلسل قابل للتحويل من الأحرف، وتوفر هذه الفئة أبي متوافقة مع سترينغبوفر، ولكن مع عدم وجود ضمان التزامن".

أنه replace ( append ، insert ، delete ، وآخرون) ويمكنك استخدام toString أن يتحول إلى String حقيقية.


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

ربما يمكن استخدام كائن ماتشر للقيام بذلك بكفاءة.


إضافة إلى الإجابةpaxdiablo، وهنا نموذج تنفيذ ريبلاسال باستخدام سترينغبوفيرز الذي هو ~ 3.7 مرات أسرع من String.replaceAll ():

الشفرة:

public static String replaceAll(final String str, final String searchChars, String replaceChars)
{
  if ("".equals(str) || "".equals(searchChars) || searchChars.equals(replaceChars))
  {
    return str;
  }
  if (replaceChars == null)
  {
    replaceChars = "";
  }
  final int strLength = str.length();
  final int searchCharsLength = searchChars.length();
  StringBuilder buf = new StringBuilder(str);
  boolean modified = false;
  for (int i = 0; i < strLength; i++)
  {
    int start = buf.indexOf(searchChars, i);

    if (start == -1)
    {
      if (i == 0)
      {
        return str;
      }
      return buf.toString();
    }
    buf = buf.replace(start, start + searchCharsLength, replaceChars);
    modified = true;

  }
  if (!modified)
  {
    return str;
  }
  else
  {
    return buf.toString();
  }
}

حالة الاختبار - الإخراج هو ما يلي (Delta1 = 1917009502؛ Delta2 = 7241000026):

@Test
public void testReplaceAll() 
{
  String origStr = "1234567890-1234567890-";

  String replacement1 =  StringReplacer.replaceAll(origStr, "0", "a");
  String expectedRep1 = "123456789a-123456789a-";

  String replacement2 =  StringReplacer.replaceAll(origStr, "0", "ab");
  String expectedRep2 = "123456789ab-123456789ab-";

  String replacement3 =  StringReplacer.replaceAll(origStr, "0", "");
  String expectedRep3 = "123456789-123456789-";


  String replacement4 =  StringReplacer.replaceAll(origStr, "012", "a");
  String expectedRep4 = "1234567890-1234567890-";

  String replacement5 =  StringReplacer.replaceAll(origStr, "123", "ab");
  String expectedRep5 = "ab4567890-ab4567890-";

  String replacement6 =  StringReplacer.replaceAll(origStr, "123", "abc");
  String expectedRep6 = "abc4567890-abc4567890-";

  String replacement7 =  StringReplacer.replaceAll(origStr, "123", "abcdd");
  String expectedRep7 = "abcdd4567890-abcdd4567890-";

  String replacement8 =  StringReplacer.replaceAll(origStr, "123", "");
  String expectedRep8 = "4567890-4567890-";

  String replacement9 =  StringReplacer.replaceAll(origStr, "123", "");
  String expectedRep9 = "4567890-4567890-";

  assertEquals(replacement1, expectedRep1);
  assertEquals(replacement2, expectedRep2);
  assertEquals(replacement3, expectedRep3);
  assertEquals(replacement4, expectedRep4);
  assertEquals(replacement5, expectedRep5);
  assertEquals(replacement6, expectedRep6);
  assertEquals(replacement7, expectedRep7);
  assertEquals(replacement8, expectedRep8);
  assertEquals(replacement9, expectedRep9);

  long start1 = System.nanoTime();
  for (long i = 0; i < 10000000L; i++)
  {
    String rep =  StringReplacer.replaceAll(origStr, "123", "abcdd");
  }
  long delta1 = System.nanoTime() -start1;

  long start2= System.nanoTime();

  for (long i = 0; i < 10000000L; i++)
  {
    String rep =  origStr.replaceAll( "123", "abcdd");
  }

  long delta2 = System.nanoTime() -start1;

  assertTrue(delta1 < delta2);

  System.out.printf("Delta1 = %d; Delta2 =%d", delta1, delta2);


}

عند استبدال الأحرف المفردة، فكر في التكرار فوق مصفوفة الأحرف الخاصة بك ولكن استبدل الأحرف باستخدام HashMap<Character, Character>() (تم إنشاؤه مسبقا) HashMap<Character, Character>() .

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

انها حوالي مرتين بسرعة مقارنة String.replace(char, char) . لاحظ أن الوقت المرتبط بإنشاء خريطة التجزئة غير مضمنة في هذه المقارنة.





replace