LINUX.ORG.RU

Java, есть ли профит от найтивной библиотеки для работы со строками?

 ,


0

3

Есть ли от этого профит? С какого количества операций/размера строк он начинается? Не рушит ли это логику работы VM/GC? Если ли такие либы в природе (нагуглить не смог), что б самому потестить?

★★★★★

Последнее исправление: ya-betmen (всего исправлений: 1)

Первый раз о таком слышу, так что нет. Если не хочешь мусора — используй интерфейс CharSequence, это в т.ч. StringBuilder.

anonymous
()

Нет, не нужно.

По крайней мере если есть сценарии использования, которые не очень покрываются стандартной библиотекой, то они никак не решаются нативностью.

Пример. Раньше если у тебя была строка и ты вызывал метод substr, то так как строки иммутабельны, то создавался новый обьект, которые ссылался на тот же buffer что и предыдущая, но с другими параметрами конца и начала строки. Buffer переиспользовался. Это позволяло экономно хранить всякие суффиксные деревья и тд. Теперь это убрали, так как могут быть утечки памяти. Как теперь решить проблему? Просто написать то же самое вручную. Не вижу сценариев для нативности если ссылки на начало и конец (в некотором роде арифметика указателей) можно и так написать

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Вообще то очевидно, что подобный подход бессмысленен в случае substring/trim, я говорил например о форматировании или склейке, никакие хаки внутри java кода не позволят выпрыгнуть за скорость StringBuilder'а.

ya-betmen ★★★★★
() автор топика

Там всё оптимизировано вусмерть, по скорости, скорее всего, будет ровно то же, что и на С. Обычно оптимизировать имеет смысл алгоритмы.

Legioner ★★★★★
()

Есть профит, если использовать SSE2/AVX потоковую обработку строк, обычно это имеет смысл только в СУБД, а не в template engine, к примеру. Также профит может быть в экономии памяти (оперативной).

menangen ★★★★★
()
Ответ на: комментарий от Legioner

Там всё оптимизировано вусмерть

Как там получается? Всё оптимизировано, а тормозит и жрет память все равно.

anonymous
()
Ответ на: комментарий от menangen

не в template engine

Почему?

Склейка строк идёт через стрингбилдер, стрингбилдер работает через Arrays.copyOf, т.е. чем больше строк нужно сложить тем большее число массивов будет создано. И тем больше раз будет вызвано копирование массива.

ya-betmen ★★★★★
() автор топика

Если строки такие же как в Java, то смысла нет. Однако, некоторый выйгрыш можно получить если хратить строки не в UTF-16, а в UTF-8 или однобайтовой кодировке (если задача позволяет).

maxcom ★★★★★
()

Вы, эта, ботлнек вначале найдите, тогда нужно/не нужно уже станет очевидным ответом.

dizza ★★★★★
()
Ответ на: комментарий от Legioner

Вот, например, пост выше Java, есть ли профит от найтивной библиотеки для работы со строками? (комментарий)

Но вообще я про java в целом. Кругом пишут, что там все оптимизировано донельзя, а чуть серьезная софтина памяти жрет дофигища и медлительно.

anonymous
()
Ответ на: комментарий от maxcom

Я не про выигрыш по памяти, я про скорость хотел бы понять. С одной стороны подсознательно чувствую, что в общем случае выигрыша не будет, но только стрингбилдер/форматтер на электровеник всё таки не тянет и если использовать найтивный код только для format(String str, Object... objects) выигрыш как будто бы должен быть.

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Вот, например, пост выше Java, есть ли профит от найтивной библиотеки для работы со строками? (комментарий)

Там написана какая то ерунда, или я не распарсил, что хотел сказать автор.

Но вообще я про java в целом. Кругом пишут, что там все оптимизировано донельзя, а чуть серьезная софтина памяти жрет дофигища и медлительно.

На любом языке есть и жрущие, есть и эффективные. В Java особо ничего не мешает писать эффективные и не жрушие программы. Ниже десятков мегабайтов потребления оперативной памяти наверное спуститься не получится, но всё остальное - на совести программиста.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Там написана какая то ерунда, или я не распарсил, что хотел сказать автор.

Как автор хочу уточнить, где именно написана ерунда или какое именно из слов во фразе «чем больше строк нужно сложить тем большее число массивов будет создано» вызвало у вас затрудение?

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Легионер, наверное, не очень силен в яве.

anonymous
()
Ответ на: комментарий от ya-betmen

Склейка строк идёт через стрингбилдер

Склейка строк идёт так, как её сделает автор. StringBuilder не единственная структура в мире, хотя и часто употребляемая.

стрингбилдер работает через Arrays.copyOf

Что это означает?

т.е. чем больше строк нужно сложить тем большее число массивов будет создано.

Каждая строка это уже массив char-ов внутри. Эта фраза точно так же не понятна. Если ты думаешь, что при каждом add будет создаваться новый массив и туда копироваться предыдущий + новая строка, то это не так.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

Хм, вспомнил тут школьный курс явы. И правда. String - тип immutable и оператор «+» на строках будет делать новый объект.

StringBuilder же - вполне мутабельная хрень, реализующая .append() с оптимизациями.

That's all, folks :)

anonymous
()
Ответ на: комментарий от ya-betmen

Потому, что там (intel sse/avx) набор команд не для склейки и копировании строк :-) а для их сравнения, результат выдаётся всякими битовыми масками, умучаешься дальше писать алгоритм, который тебе будет полезен в template engine.

menangen ★★★★★
()
Ответ на: комментарий от Legioner

Там всё оптимизировано вусмерть, по скорости, скорее всего, будет ровно то же, что и на С

а в glibc используются sse*/avx/etc

anonymous
()
Ответ на: комментарий от Legioner

StringBuilder не единственная структура в мире, хотя и часто употребляемая.

Не единственная, но «aaa» + «bbb» будет приведено именно к стрингбилдеру. Можно использовать форматтер, но по скорости он выигрыша не даёт. Что ещё, клеить руками?

Если ты думаешь, что при каждом add будет создаваться новый массив и туда копироваться предыдущий + новая строка, то это не так.

У меня что, исходники от какой-то другой ждк?

public static char[] copyOf(char[] original, int newLength) {
    char[] copy = new char[newLength];
    System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    return copy;
}

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

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

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

maloi ★★★★★
()
Ответ на: комментарий от ya-betmen

У меня что, исходники от какой-то другой ждк?

а теперь _внимательно_ прочитай место, где этот метод вызывается.

maloi ★★★★★
()
Ответ на: комментарий от maloi

Именно об этом случае я и писал. Если я заранее знаю формат строки и число объектов, будет ли выигрыш от того сделаю я это в либе или средствами java?

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

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

на мой взгляд - профита не будет, кроме того, если у тебя тормозит работа со строками, то ты неправильно с ними работаешь (или запускаешь свое приложение на наручных часах)

maloi ★★★★★
()
Последнее исправление: maloi (всего исправлений: 1)
Ответ на: комментарий от maloi

вопрос в том, тормозит у тебя сейчас что-то или ты поболтать пришел?

Считай что поболтать.

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

В этом случае нужно говорить: «Я не знаю».

на мой взгляд - профита не будет

Я бы хотел узнать мнение тех, кто проводил подобные эксперименты/может аргументировать свою мысль.

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Не единственная, но «aaa» + «bbb» будет приведено именно к стрингбилдеру.

Подожди. Ты путаешь понятия. Зачем вообще делать «aaa» + «bbb», если тебе нужен StringBuilder? Делаешь объект именно стрингбилдера, затем аппендишь/ремувишь/делаешьчохочешь с ним. И никаких копирований не будет.

anonymous
()
Ответ на: комментарий от anonymous

Зачем вообще делать «aaa» + «bbb»

Потому что
1. Я не хочу бегать наперегонки с оптимизатором
2. Я не хочу убивать читабельность кода

И никаких копирований не будет.

Если бы.

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от windofchange

иммутабельны, но при вызове substr всегда создается новый char[]

maloi ★★★★★
()
Ответ на: комментарий от ya-betmen

1. Я не хочу бегать наперегонки с оптимизатором

ты бы документацию хотя бы почитал, прежде чем говорить об оптимизаторах

2. Я не хочу убивать читабельность кода

и какая будет читабельность у нативного кода?

Если бы.

не будет, если ты этого захочешь.

maloi ★★★★★
()
Ответ на: комментарий от ya-betmen

У меня что, исходники от какой-то другой ждк?

иногда лучше мозги чем исходники jdk, хотябы для того чтобы прочитать документацию

Deleted
()

Вызов нативного метода и возврат обратно в джаву может иметь более высокие накладные расходы, чем если оставить строку без оптимизации.

dycore
()
3 января 2015 г.
Ответ на: комментарий от stevejobs

разве «aaa» + «bbb» и так не превращается в StringBuilder в ходе компиляции

Превращается. А вот String.format(«%s%s», new Object[]{«aaa»,«bbb»}) не превращается.

Я поковырялся, от найтивки профита нет, а вот ускоренную шаблонизацию запилить удалось. Правда быстрее она не намного а вот память экономит в разы.

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

а вот ускоренную шаблонизацию запилить удалось

как?

я просто сейчас с Wicket разбираюсь. Там всё довольно печально, а скорость шаблонизации совсем вговно

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

как?

Принцип простой, делаем массив char, ищем паттерн, если нашли рассчитываем длины, копируем один кусок из шаблона, второй из замены, пока стока не кончится.

Мне, например, нужна была замена для String.format. Просто в качестве хобби ковыряю свой фреймворк, нужен был простой но быстрый внутренний шаблонизатор. Он всех фич не учитывает, только клеит строки, но мне больше ничего и не нужно было т.к. конвертеры у меня отдельные.

    private static final String NULL = "null";

    private static String getString(Object obj) {
        if (obj == null) {
            return NULL;
        } else if (String.class.equals(obj.getClass())) {
            return (String) obj;
        } else {
            return obj.toString();
        }

    }

    public static String format(String format, Object... args) {
        int sourceOffset = 0;
        int targetOffset = 0;
        int len = format.length();
        char[] result = new char[len];
        for (Object arg : args) {
            String replace = getString(arg);
            int sourceChunkEnd = format.indexOf("%s", sourceOffset);
            if (sourceChunkEnd > -1) {
                int repLen = replace.length();
                int srcLen = sourceChunkEnd - sourceOffset;
                if (len < targetOffset + repLen + srcLen) {
                    len = len * 2 + repLen + srcLen;
                    result = Arrays.copyOf(result, len);
                }
                format.getChars(sourceOffset, sourceChunkEnd, result, targetOffset);
                targetOffset += sourceChunkEnd - sourceOffset;
                replace.getChars(0, repLen, result, targetOffset);
                sourceOffset = sourceChunkEnd + 2;
                targetOffset += repLen;
            } else {
                break;
            }
        }
        int sourceChunkEnd = format.length();
        int srcLen = sourceChunkEnd - sourceOffset;
        if (len < targetOffset + srcLen) {
            len = len + srcLen;
            result = Arrays.copyOf(result, len);
        }
        format.getChars(sourceOffset, sourceChunkEnd, result, targetOffset);
        targetOffset += sourceChunkEnd - sourceOffset;
        return new String(result, 0, targetOffset);
    }

String.format производит кучу мусора, поэтому сильно добавляет GC работы. Моя замена фактически быстрее всего на 5-15%, но в целом при ограничении в 4гб для томката получил значительный выигрыш после 150 параллельных юзеров, ибо среднее время отклика со String.format при 200 юзерах улетело за 20 сек, а мой вариант так и остался в пределах 2.5.

Я на этом сниппете ещё и скоростной форматтер логов делал, он был в несколько раз быстрее стандартного.

Wicket

Его сильно допилили? Помню года 4 назад пробовал, там был дичайший оверхед и глюки при любом отходе от success path.

ya-betmen ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Его сильно допилили?

поставил новую версию, детальных тестов пока не делал, но внешне - это всё то же самое говнецо со слегка пофиксеным API

хочу сейчас надругаться и сделать класс типа ScalatePanel, который будет разметку брать из текстового файла в обход всей этот викет-мутотени. Т.е. я согласен, что какими-то глобальными вещами в Wicket управлять удобно, эти его панели можно рассматривать как отдельные под-приложения (типа портлетов), но делать таким образом простой список или таблицу - увольте.

stevejobs ★★★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.