2015-05-11 4 views
0

У меня есть беспокойство относительно того, как java сравнивает String и насколько она оптимизирована.Процесс сравнения строк Java

Давайте рассмотрим, что мне требуется сравнить предоставленный пользователем String, с 10 строк в моем коде. Из этих 10 строк 5 начинаются с «А», а остальные 5 начинаются с «В».

Теперь, если я пишу if..elseif.. или switch, то каждая строка будет сравниваться, пока он не совпадет с любой строкой, а при худшем случае, когда либо строка становится согласованной в 9-м или 10-м состоянии или нет вообще. Таким образом, для каждого входа выполняется среднее значение от 8 до 10 условий.

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

if(inputString.charAt(0) == 'A'){ 
      if(){ 
       .... 
      }else if(){ 
       .... 
      } 
     }else if(inputString.charAt(0) == 'B'){ 
      if(){ 
       ... 
      }else if(){ 
       ... 
      } 
     } 

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

+1

Поместите десять строк в массив, сравните с тем, что в цикле, сломайте, если true ... –

+0

@TonyHopkinson, но это уменьшит только строку кода, но условия будут одинаковыми в обоих случаях. – Vicky

+0

Если вы посмотрите на реализацию [String # equals] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java#1012), вы заметите, что 'str1.equals (str2)' - самый эффективный способ сделать то, что вам нужно, не записывая компилируемый/трудно понятный код, как вы опубликовали. – kiruwka

ответ

0

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

+0

Как насчет времени, затраченного на создание карты/набора ?. Это не хорошее решение? – TheLostMind

+0

Это зависит от характера «10 строк в моем коде». Статичны ли они? – sudocode

+0

Откровенно говоря - * ничто не может бить доступ к массиву * во временной сложности. Честно говоря, использование 'Set' или' Map' вообще неэффективно. Представьте себе время, затраченное на все, что нужно поддержать, что не обязательно. И наихудшее время доступа к «HashMap» не является «O (1)». – TheLostMind

0

Java сравнить строки символов по характеру. С вашей «оптимизацией» вы сравниваете еще один символ, чем нужно каждый раз. Вы начинаете сравнивать первый символ (A или B), а затем все слово включает в себя снова первый символ.

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

И еще одна вещь ... если вы используете переключатель, время, затраченное на поиск, не зависит по количеству элементов ... поэтому первая оптимизация не нужна, если вы используете переключатель.

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

1

Условный оператор

Дискуссии обычно начинаются окружающий комплекс, если такие заявления такие:

if (value == 0){ 
    return result0; 
} else if (value == 1){ 
    return result1; 
} else if (value == 2){ 
    return result2; 
} else if (value == 3){ 
    return result3; 
} else if (value == 4){ 
    return result4; 
} else if (value == 5){ 
    return result5; 
} else if (value == 6){ 
    return result6; 
} else if (value == 7){ 
    return result7; 
} else if (value == 8){ 
    return result8; 
} else if (value == 9){ 
    return result9; 
} else { 
    return result10; 
} 

Как правило, этот тип конструкции нахмурился. Основная проблема заключается в том, что чем глубже в заявлении, выполняемом потоком, тем больше условий нужно оценивать. Для завершения выполнения потребуется больше времени, если значение равно 9, чем если значение равно 0, потому что каждое другое условие должно быть оценено заранее. По мере того, как общее количество условий увеличивается, так же, как и производительность, уходит глубоко в условия. Несмотря на то, что при наличии большого количества условий не рекомендуется, вы можете предпринять шаги для повышения общей производительности.

Первый шаг - упорядочить условия в порядке убывания частоты. Поскольку выход после первого условия - это самая быстрая операция, вы хотите убедиться, что это происходит как можно чаще. Предположим, что наиболее распространенным случаем в предыдущем примере является то, что значение будет равно 5, а второе наиболее распространенное - это значение, равное 9.В этом случае вы знаете, что пять условий будут оценены, прежде чем перейти к наиболее распространенному случаю и девяти, прежде чем перейти ко второму наиболее частому случаю; это невероятно неэффективно. Даже при том, что увеличение числовой порядок условий делает его легче читать, он на самом деле следует переписать следующим образом:

if (value == 5){ 

    return result5; 
} else if (value == 9){ 
    return result9; 
} else if (value == 0){ 
    return result0; 
} else if (value == 1){ 
    return result1; 
} else if (value == 2){ 
    return result2; 
} else if (value == 3){ 
    return result3; 
} else if (value == 4){ 
    return result4; 
} else if (value == 6){ 
    return result6; 
} else if (value == 7){ 
    return result7; 
} else if (value == 8){ 
    return result8; 
} else { 
    return result10; 
} 

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

Еще один способ оптимизации операторов if состоит в том, чтобы организовать условия в ряд ветвей, следуя алгоритму бинарного поиска, чтобы найти действительное условие. Это целесообразно в случае, когда возможно большое количество условий, и ни один, ни два не будут происходить с достаточно высокой скоростью, чтобы просто упорядочить по частоте. Цель состоит в том, чтобы свести к минимуму количество условий, которые должны быть оценены для максимально возможного количества условий. Если все условия для значения в примере будет происходить с той же относительной частоте, если заявления можно переписать следующим образом:

if (value < 6){ 

    if (value < 3){ 
     if (value == 0){ 
      return result0; 
     } else if (value == 1){ 
      return result1; 
     } else { 
      return result2; 
     } 
    } else { 
     if (value == 3){ 
      return result3; 
     } else if (value == 4){ 
      return result4; 
     } else { 
      return result5; 
     } 
    } 

} else { 

    if (value < 8){ 
     if (value == 6){ 
      return result6; 
     } else { 
      return result7; 
     } 
    } else { 
     if (value == 8){ 
      return result8; 
     } else if (value == 9){ 
      return result9; 
     } else { 
      return result10; 
     } 

    } 
} 

Этот код гарантирует, что никогда не будет больше, чем четыре условия оценены. Вместо того, чтобы оценивать каждое условие для нахождения правильного значения, условия сначала разделяются на ряд диапазонов, прежде чем идентифицировать фактическое значение. Общая производительность этого примера улучшена, потому что были удалены случаи, когда необходимо оценить восемь и девять условий. Максимальное количество оценок условий теперь составляет четыре, создавая среднюю экономию около 30% от времени выполнения предыдущей версии. Имейте в виду также, что инструкция else не имеет никакого условия для оценки. Однако проблема остается в том, что каждое дополнительное условие заканчивается тем, что требуется больше времени для выполнения, что влияет не только на производительность, но и на поддерживаемость этого кода. Здесь оператор переключатель приходит.

Переключатель заявление

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

switch(value){ 
    case 0: 
     return result0; 
    case 1: 
     return result1; 
    case 2: 
     return result2; 
    case 3: 
     return result3; 
    case 4: 
     return result4; 
    case 5: 
     return result5; 
    case 6: 
     return result6; 
    case 7: 
     return result7; 
    case 8: 
     return result8; 
    case 9: 
     return result9; 
    default: 
     return result10; 
} 

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

Другой вариант: Array поиска

Есть более двух решений для работы с условными в JavaScript. Наряду с если заявление и заявление переключателя третий подход: отрываясь значения в массивах

for(String s: arr){ 
    if(s.equals(targetValue)) 
     return true; 
} 
return false; 

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

Самыми быстрыми условные

три методики, представленных здесь-ИФ заявление, заявление переключателя, и массив поиск, каждый имеет свое применение в оптимизации выполнения кода:

• Используйте, если заявление, когда:

  • Там нет более двух дискретных значений, для которых необходимо проверить.
  • Существует большое количество значений, которые можно легко разделить на диапазоны.

• Используйте оператор переключатель, когда:

  • Есть более двух, но меньше, чем 10 дискретных значений, для которых для тестирования.
  • Для условий нет диапазонов, поскольку значения нелинейны.

• Используйте поиск массива, когда:

  • Есть более 10 значений, для которых необходимо проверить.
  • Результаты условий являются отдельными значениями, а не числом действий, которые необходимо предпринять.
Смежные вопросы