Что более эффективно «||» или цикл?

#java #if-statement #for-loop #performance

#java #if-оператор #для цикла #Производительность

Вопрос:

Давайте просто скажем, что вам нужно отредактировать ряд слов из arraylist («cat», «dog», «catdog», «mandog»)

Теперь вы можете либо поместить это в цикл for, вот так

  for(int i=0; i<arraylist.size(); i  ){
    if(arraylist.get(i).matches("cat") || arraylist.get(i).matches("dog") etc.. etc..
      {
        //do something
      }
   }
  

Или вы можете поместить слова (cat, dog, catdog и mandog) в массив строк / arraylist и сравнить их, используя это.

Какой из них более эффективен?

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

Спасибо за помощь.

Комментарии:

1. Более эффективным является извлечение arrayList.get(i) операции из if, чтобы она оценивалась только один раз.

2. Я сомневаюсь, что это будет иметь такое большое значение. Здесь более важна удобочитаемость кода: вам не нужен гигантский оператор if, который явно сравнивает .get(i) с каждым словом

3. Ни то, ни другое. Поместите слова в набор и посмотрите, есть ли arraylist.get(i) в наборе.

4. Кроме того, использовать matches() , когда на самом деле регулярное выражение не используется, тоже не самое мудрое, что можно сделать.

5. Какой тип операции вы хотите выполнить с этими строками ?

Ответ №1:

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

Учитывая, что список слов может стать довольно большим, вам следует использовать Set . HashSet Может выполнять contains проверку в постоянное время, что делает его очень подходящим для этой цели. Итак:

 Set<String> keywords = new HashSet<>();

keywords.add("cat");
keywords.add("dog");
// ...

for (String element: arraylist) {
    if (keywords.contains(element)) {
        // Do something
    }
}
  

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

Комментарии:

1. HashSet — это лучший способ проверить, содержит элемент или нет, и это делается в постоянное время. Обратите внимание, что метод contains чувствителен к регистру, и он не будет работать, если вы хотите сравнить со строкой «Cat» из данного примера кода, тогда рекомендуется добавить ключевое слово в нижнем регистре и сравнивать только в режиме нижнего регистра, например.

Ответ №2:

Я думаю, что подходящий способ (хотя и намного больше работы) — протестировать все варианты. Используйте профилировщик, чтобы увидеть, сколько времени требуется вашему коду для выполнения поиска, а затем перейдите к процессу, который дает наилучшие результаты.

Без использования профилировщика очень сложно определить улучшения в производительности.

Комментарии:

1. Не всегда. Если вы можете заменить структуру данных другой в более сложном по времени классе для необходимых вам операций (например, HashSet против ArrayList для сдерживания), вы почти наверняка внесете улучшение производительности.

2. @StefanoSanfilippo Да, вы правы. Это также отличный способ обеспечить повышение производительности кода. Однако вам все равно было бы трудно объективно определить, какие изменения улучшили код, без какого-либо способа его измерения.

Ответ №3:

Поскольку вы используете matches() метод в своем коде, я предполагаю, что вам нужно выполнить сопоставление с регулярным выражением. Если это так, вы могли бы использовать вложенный цикл for.

 String[] patterns = {"cat", "dog"};
for(String item : arraylist){
    for(String pattern : patterns){
        if(item.matches(pattern)){
            //do something
        }
    }
}
  

Если вы просто хотите проверить, присутствует ли строка в списке, вы могли бы использовать подход Стефано Санфилиппо.

Комментарии:

1. Нет необходимости оборачивать patterns массив в список, вы также можете выполнять итерации по массивам.

2. ДА. Извините, это был просто мой обычный стиль кодирования.. Отредактировано .. 🙂

3. Если и список массивов, и группа шаблонов содержат много записей, вы можете объединить шаблоны программно (используя скобки и | ) в один шаблон, скомпилировать его один раз, а затем сопоставить со всеми элементами списка массивов. Но, похоже, «совпадения» на самом деле не были необходимы.