Когда я недавно работал в большой компании, я заметил, что программисты придерживались этого стиля кодирования:
Предположим, у меня есть функция, которая возвращает 12, если вход A, 21, если B, и 45, если C.
Так что я могу написать сигнатуру функции как:
int foo(String s){
if(s.equals("A")) return 12;
else if(s.equals("B")) return 21;
else if(s.equals("C")) return 45;
else throw new RuntimeException("Invalid input to function foo");
}
Но при проверке кода меня попросили изменить функцию на следующую:
int foo(String s){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 12);
map.put("B", 21);
map.put("C", 45);
return map.get(s);
}
Я не могу убедить себя, почему второй код лучше первого. Второй код определенно займет больше времени для запуска.
Единственной причиной использования второго кода может быть то, что он обеспечивает лучшую читаемость. Но если функция вызывается много раз, разве вторая функция не замедлит время работы вызывающей ее утилиты?
Что Вы думаете об этом?
coding-style
coding-standards
Nikunj Banka
источник
источник
switch
кажется более подходящей, чемif-else
). Но в какой-то момент это становится проблематичным. Основным преимуществом использования карты является то, что вы можете загрузить ее из файла, таблицы и т. Д. Если вы жестко программируете входные данные для карты, я не вижу большой ценности по сравнению с переключателем.Ответы:
Смысл в том, чтобы переместить создание хэш-карты за пределы функции и сделать это один раз (или просто меньше, чем в противном случае).
Однако с тех пор java7 может иметь (окончательные) строки в переключателях:
источник
Во втором примере
Map
должен быть закрытый статический член, чтобы избежать избыточных издержек инициализации.Для большого количества значений карта будет работать лучше. Используя хеш-таблицу, можно искать ответ за постоянное время. Конструкция множественного if должна сравнивать входные данные с каждой из возможностей, пока не найдет правильный ответ.
Другими словами, поиск карты - это O (1), а
if
s - это O (n), где n - это количество возможных входных данных.Создание карты O (n), но выполняется только один раз, если это статическое постоянное состояние. Для часто выполняемого поиска карта будет превосходить
if
операторы в долгосрочной перспективе за счет чуть большего времени, когда программа запускается (или класс загружается, в зависимости от языка).При этом карта не всегда является подходящим инструментом для этой работы. Хорошо, когда значений много, или значения должны быть конфигурируемыми с помощью текстового файла, пользовательского ввода или базы данных (в этом случае карта действует как кэш).
источник
В программном обеспечении есть две скорости: время, необходимое для записи / чтения / отладки кода; и время, необходимое для выполнения кода.
Если вы можете убедить меня (и ваших рецензентов кода), что функция hashmap действительно медленнее, чем if / then / else (после рефакторинга для создания статического hashmap) И вы можете убедить меня / рецензентов, что ее вызывали достаточно раз, чтобы сделать фактическую Разница, а затем замените хэш-карту с if / else.
В противном случае код хэш-карты будет в высшей степени читаемым; и (вероятно) без ошибок; Вы можете определить это быстро, просто посмотрев на него. Вы не можете сказать то же самое о if / else, не изучив его; разница еще более преувеличена, когда есть сотни вариантов.
источник
Я очень предпочитаю ответ в стиле HashMap.
Для этого есть метрика
Существует метрика качества кода, которая называется Cyclomatic Complexity . Эта метрика в основном подсчитывает количество различных путей в коде ( как вычислить цикломатическую сложность ).
Для каждого возможного пути выполнения метод становится все сложнее и сложнее понять и полностью проверить на правильность.
Это сводится к тому, что «управляющие ключевые слова», такие как: ifs, elses, whiles и т. Д. ... используют булевы тесты, которые могут быть ошибочными. Повторное использование «контрольных ключевых слов» приводит к хрупкому коду.
Дополнительные преимущества
Кроме того, «картографический подход» побуждает разработчиков думать о парах ввода-вывода как о наборе данных, который можно извлекать, использовать повторно, манипулировать во время выполнения, тестировать и проверять. Например, ниже я переписал «foo», чтобы мы не были постоянно заблокированы в «A-> 12, B-> 21, C-> 45»:
rachet_freak упоминает этот тип рефакторинга в своем ответе, он утверждает скорость и повторное использование, я выступаю за гибкость времени выполнения (хотя использование неизменяемой коллекции может иметь огромные преимущества в зависимости от ситуации)
источник
Данные лучше чем код. Не в последнюю очередь потому, что слишком заманчиво добавить еще одну ветвь в код, но добавить строку в таблицу сложно, чтобы ошибиться. Этот вопрос является небольшим примером этого. Вы пишете таблицу поиска. Либо напишите реализацию, дополненную условной логикой и документацией, либо напишите таблицу и посмотрите в ней.
Таблица данных всегда является лучшим представлением некоторых данных, чем код, по модулю оптимизации. То, насколько трудно выразить таблицу, может зависеть от языка - я не знаю Java, но надеюсь, что она может реализовать справочную таблицу проще, чем пример в OP.
Это таблица поиска в Python. Если это рассматривается как вызывающий конфликт, учтите, что вопрос не помечен как java, рефакторинг не зависит от языка, и что большинство людей не знают java.
Идея реструктуризации кода для сокращения времени выполнения имеет смысл, но я бы предпочел использовать компилятор, который поднимает общую настройку, чем сам.
источник