Я полагаю, что сравнение nvarchars является более дорогостоящим, чем varchars, таким образом, это совершенно допустимо и даже предпочтительно в местах, где Вам действительно не нужны unicode возможности, т.е. для некоторых внутренних идентификаторов.
И затраты на хранение все еще действительно имеет значение . Если у Вас есть миллиарды строк тогда, те "небольшие" различия становятся большими довольно быстро.
Согласно документации для String.replaceAll
, о вызове метода говорится следующее:
Вызов этого метода форма
str.replaceAll (регулярное выражение, repl)
дает точно такой же результат, как и выражениеPattern.compile (регулярное выражение) .matcher (str) .replaceAll (repl)
Следовательно, можно ожидать, что производительность между вызовом String.replaceAll
и явным созданием Matcher
и Pattern
должна быть одинаковой.
] Edit
Как было указано в комментариях, несуществующая разница в производительности будет верна для одного вызова replaceAll
из String
или Matcher
, однако, если нужно выполнить несколько вызовов replaceAll
, можно ожидать, что будет полезно сохранить скомпилированный шаблон
, поэтому относительно дорогостоящая компиляция шаблона регулярного выражения не нужно выполнять каждый раз.
Исходный код String.replaceAll ()
:
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
Он должен сначала скомпилировать шаблон - если вы собираетесь запускать его много раз с одним и тем же шаблоном на коротких строках производительность будет намного выше, если вы повторно используете один скомпилированный шаблон.
Основное отличие состоит в том, что если вы удерживаете шаблон
, используемый для создания Matcher
, вы можете избежать повторной компиляции регулярного выражения каждый раз, когда вы его используете. . Проходя через String
, вы не получаете возможности «кэшировать», как это.
Если у вас каждый раз другое регулярное выражение, используйте String
класс replaceAll
в порядке. Если вы применяете одно и то же регулярное выражение ко многим строкам, создайте один Pattern
и повторно используйте его.
Неизменяемость / безопасность потоков: скомпилированные шаблоны неизменяемы, сопоставители - нет. (см. Является ли Java Regex Thread Safe? )
Обработка пустых строк: replaceAll должен корректно обрабатывать пустые строки (это не соответствует шаблону пустой входной строки)
Приготовление кофе и т. д .: последний Я слышал, что ни String, ни Pattern, ни Matcher не имеют для этого каких-либо функций API.
edit: что касается обработки NULL, документация для String и Pattern явно не говорит об этом, но я подозреваю, что они вызовут исключение NullPointerException, поскольку они ожидать String.
Реализация String.replaceAll
сообщает вам все, что вам нужно знать:
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
(И документы говорят то же самое.)
Пока я не знаю ' t проверил кеширование, я бы конечно ожидал, что компиляция шаблона один раз и сохранение статической ссылки на него будет более эффективным, чем вызов Pattern.compile
с тем же шаблоном каждый раз. Если есть кэш, это будет небольшая экономия эффективности - если его нет, то он может быть большим.
Разница в том, что String.replaceAll () компилирует регулярное выражение при каждом его вызове. Нет эквивалента для статического метода Regex.Replace () .NET, который автоматически кэширует скомпилированное регулярное выражение. Обычно replaceAll () - это то, что вы делаете только один раз, но если вы собираетесь вызывать его повторно с одним и тем же регулярным выражением, особенно в цикле, вам следует создать объект Pattern и использовать метод Matcher.
Вы можете также заранее создайте Matcher и используйте его метод reset () для перенацеливания его при каждом использовании:
Matcher m = Pattern.compile(regex).matcher("");
for (String s : targets)
{
System.out.println(m.reset(s).replaceAll(repl));
}
Выигрыш в производительности от повторного использования Matcher, конечно, нигде не так велик, как от повторного использования Pattern.