Возможное повышение производительности для AbstractStringBuilder - PullRequest
3 голосов
/ 08 марта 2012

Я делал тесты с Java StringBuilder, особенно с функцией replace (int, int, String), которая реализована в классе AbstractStringBuilder следующим образом:

public AbstractStringBuilder replace(int start, int end, String str) {
    if (start < 0)
        throw new StringIndexOutOfBoundsException(start);
    if (start > count)
        throw new StringIndexOutOfBoundsException("start > length()");
    if (start > end)
        throw new StringIndexOutOfBoundsException("start > end");

    if (end > count)
       end = count;
    int len = str.length();
    int newCount = count + len - (end - start);
    if (newCount > value.length)
       expandCapacity(newCount);

    System.arraycopy(value, end, value, start + len, count - end);
    str.getChars(value, start);
    count = newCount;
    return this;
}

Вызов функции Arraycopy «перемещает» части содержимого массива символов значения, чтобы освободить место для последующего введенного содержимого str (str.getChars (value, start)). С моей точки зрения, эту копию массива следует выполнять только в том случае, если длина строки не соответствует пространству, которое должно быть перезаписано в массиве символов.

Очевидно, что очень отчаянно желает считать это проблемой производительности, хотя проведение тестов с большими символьными массивами (> 500 тыс. Символов) и копированием массивов в классе замены StringBuilder привело к ощутимому улучшению производительности.

Протестировано с java 6 на 32-битной платформе Windows на том же экземпляре StringBuilder для нескольких миллионов замененных вызовов.

Считаете ли вы это неважным, ошибкой или я что-то упустил полностью?

1 Ответ

1 голос
/ 08 марта 2012

Я бы передал его как запрос на улучшение.

Что-то вроде

if (end != start + len)
    System.arraycopy(value, end, value, start + len, count - end);

Еще одним улучшением будет изменение копии массива.

public static void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length) {
    if (srcPos != destPos && length != 0)
       arraycopy0(src, srcPos, dest, destPos, length);

}

private static native void arraycopy0(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);
...