Строка оптимизации Java vs Char Массивы

В программе, которую я пишу, я делаю много строковых манипуляций. Я пытаюсь повысить производительность и задаюсь вопросом, будет ли использование массивов char достойным увеличением производительности. Любые предложения?

Ответ 1

Какую манипуляцию вы делаете? Можете ли вы опубликовать образец кода?

Вы можете взглянуть на StringBuilder, который реализует CharSequence для повышения производительности. Я не уверен, что вы хотите бросить свои собственные. StringBuilder не является потокобезопасным btw... если вы хотите, чтобы безопасность потока смотрела на StringBuffer.

Ответ 2

Строка уже реализована как массив char. Что вы планируете делать по-другому? В любом случае, между тем и тем фактом, что GC для эфемерных объектов чрезвычайно быстр, я был бы поражен, если бы вы могли найти способ увеличить производительность, заменив массивы char.

Майкл Боргвардт советует о небольших массивах char и использует StringBuilder и StringBuffer очень хорошо. Но для меня главное - попытаться не догадываться о том, что медленно: делать измерения, использовать профилировщик, получать определенные факты. Потому что обычно наши догадки о производительности оказываются неправильными.

Ответ 3

Вот выдержка из полного источника класса String из JDK 6.0:

 public final class String implements  java.io.Serializable,
       Comparable<String>, CharSequence {
       /** The value is used for character storage. */
        private final char value[];

       /** The offset is the first index of the storage that is used. */
       private final int offset;

        /** The count is the number of characters in the String. */
       private final int count;

Как вы можете видеть внутренне, значение уже сохраняется как массив символов. Массив символов как структуры данных имеет все ограничения класса String для большинства строковых манипуляций: массивы Java не растут, т.е. Каждый раз (нормально, может быть, не каждый раз) ваша строка должна расти, вам понадобится выделить новый массив и скопировать содержимое.

Как было предложено ранее, имеет смысл использовать StringBuilder или StringBuffer для большинства строковых манипуляций.

Фактически следующий код:

   String a = "a";
   a=a+"b";
   a=a+"c";

Когда скомпилированный файл будет автоматически преобразован в использование StringBuilder, это можно легко проверить с помощью javap.

Как правило, редко бывает целесообразно тратить время на повышение производительности основных классов Java, если только вы не являетесь экспертом мирового класса по этому вопросу, просто потому, что этот код был написан экспертами мирового класса в первом место.

Ответ 4

Профилировали ли вы свое приложение? Вы знаете, где узкие места? Это первый шаг, если производительность является дополнительной. Что ж, это и определение допустимых показателей производительности.

Как только вы профилируете выполнение некоторых задач, у вас будет процент времени, затраченного на выполнение каких-либо действий. Если вы тратите много времени на использование строк, возможно, вы можете начать кэшировать некоторые из этих манипуляций? Вы делаете некоторые из них неоднократно, когда делать их только один раз будет достаточно (а затем использовать этот результат снова позже, когда это необходимо)? Вы копируете строки, когда вам это не нужно? Помните, что java.lang.String неизменен - ​​поэтому его нельзя напрямую изменить.

Я несколько раз обнаружил, что оптимизирую/улучшаю настройки системы, над которыми я работаю, я не знаю, откуда медленная инстанция исходит. Я видел других (и, позорно, я сам), трачу дни, оптимизируя что-то, что не дает выигрыша, потому что это не было первоначальным узким местом, и на самом деле это было менее 1% времени.

Надеемся, что это поможет вам в правильном направлении.

Ответ 5

Когда у вас очень большое количество коротких строк, использование char[] вместо этого может сэкономить довольно немного памяти, что также означает большую скорость из-за меньших промахов в кеше.

Но с большими строками главное, что нужно искать, - это избежать ненужного копирования, в результате чего сохраняется неизменность String. Если вы делаете много конкатенирования или замены, использование StringBuilder может иметь большое значение.