Самый быстрый способ сравнения строк (буквенный и числовой) - PullRequest
6 голосов
/ 27 августа 2009

У меня проблема с производительностью, связанная со сравнением строк (в Java).

Я работаю над проектом, который должен отсортировать огромный список (TableViewer в Eclipse). В любом случае, я определил узкое место в вызове compareTo () для сравниваемой строки.

Есть ли способ оптимизировать производительность сравнения строк? Я искал и гуглил безрезультатно ...

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

Любые предложения будут с благодарностью.

РЕДАКТИРОВАТЬ: Я забыл упомянуть, что мне нужно как числовое сравнение, так и буквальное сравнение строк.

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

EDIT3: Я знаю, что многие из вас были обеспокоены попыткой try () - catch (). На самом деле это не так важно, потому что даже если я удаляю этот код и выполняю только блок catch (одиночный compareTo ()), он все равно выполняется практически с той же скоростью, что и исходный код. Однако, если я закомментирую CompareTo () также; оставляя мне только накладные расходы на функцию сравнения (получение меток и т. д.), это молниеносно. Поэтому мне все еще нужен лучший способ сравнения строк. Либо с помощью кеширования, либо с помощью какой-то другой магии.

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

РАЗЪЯСНЕНИЯ:

Функция сравнения реализована как часть платформы TableViewer для выполнения операций сортировки, что означает, что я не реализую конкретный алгоритм сортировки, а реализован SWT / JFace. Я только реализую функцию сравнения.

Еще более интересным является тот факт, что код для сортировки парных чисел на быстрее , чем сравнение строк. Сортировать столбцы только с числами быстрее, чем с реальными буквенными строками ... Что приводит меня к выводу, что в методе compareTo () происходит что-то подозрительное ...

Вот ядро ​​функции:

// e1Label and e2Label is Strings to be compared
//

// Be smart about the comparison and use non-lexical comparison if
// possible (i.e. if both strings are actually numbers...)
//
// Warning: This is only "semi-smart" as the sorting might get "a bit"
// messed up if some of the values in a column can be parsed as
// doubles while others can not...
//
try {
    // Try using numeric (double) comparison of label values
    //
    double e1_double = Double.parseDouble(e1Label);
    double e2_double = Double.parseDouble(e2Label);
    rc = Double.compare(e1_double, e2_double);
} catch (NumberFormatException e) {
    // Use lexical comparison if double comparison is not possible
    //
    rc = e1Label.compareToIgnoreCase(e2Label);
}

Ответы [ 12 ]

0 голосов
/ 27 августа 2009

Как уже говорил Ренье и Гийом, String.compareTo () не виноват. Это должно быть медленнее, чем числовое сравнение, но не так уж важно.

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

Если это вариант, я бы выполнил поиск в фоновом режиме, то есть прикрепил бы к строкам какое-то индексирование.

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

В зависимости от наиболее распространенной операции вы можете выбрать более подходящую структуру данных.

0 голосов
/ 27 августа 2009

Если вам нужно как "буквальное", так и "числовое" сравнение, то какие данные содержат эти строки? Они всегда представляют числа?

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

И если вам нужно «буквальное» сравнение (которое я интерпретирую как сортировку «100» перед «20»), то вы можете легко реализовать это на int с или long с некоторой математикой, которая, вероятно, все еще намного быстрее чем сравнение строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...