2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|||||||||||
1 | |||||||||||
Оптимизируется ли компилятором конструкция switch-case? Работа со строками через ID объекта или hash10.06.2015, 21:13. Показов 3489. Ответов 38
Метки нет (Все метки)
Добрый вечер,
1) Определён ли порядок выбора switch (согласно стандарта кажись неопределён, но все компиляторы я уверен в этом тривиальном вопросе работают в примерно одном русле) 2) какие варианты оптимизации кода
4) сработает ли какая-либо оптимизация компилятора, если в метод который заходят часто есть константный строки
0
|
10.06.2015, 21:13 | |
Ответы с готовыми решениями:
38
Оптимальная конструкция switch-case-while / while-switch-case Конструкция выбора switch-case Не работает конструкция switch-case Ошибки при создании объекта внутри switch case |
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|
11.06.2015, 16:27 | 23 |
1
|
11.06.2015, 18:53 | 24 |
Сообщение было отмечено DrOffset как решение
Решение
Кстати, код
C++ if (str == "one") { ... } else if ( str = "two") { ... } else if ( str = "three") { ... } else if ( str = "four") { ... // длинная цепочка сравнений C++ switch (str[0]) { case 'o': if (str == "one") { ... } break; case 't': if (str == "two") { ... } else if (str == "three") { ... } break; case 'f': if (str == "four") { ... } break; }
1
|
11.06.2015, 19:20 | 25 | |||||
Тогда можно еще попробовать немного укорить:
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
11.06.2015, 20:10 [ТС] | 28 |
DrOffset, во уже что-то сладенькое. Вы это сами писали или есть где почитать про такой путь оптимизации строкового свича?
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
11.06.2015, 20:12 | 29 |
Посчитается для литералов в compile-time. Для входной строки в swicth - один проход по строке. Это быстрее, чем n-раз сравнивать c n литералами (n-проходов в худшем случае).
Добавлено через 1 минуту Писал сам. Но подход старый как мир. Просто раньше не было красивого способа посчитать hash от литерала в ct (см. boost::mpl::string), поэтому это не пользовалось популярностью.
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
11.06.2015, 20:26 | 31 |
Ну так strcmp тоже требует пройтись по строке. Так что вариант без хеша будет лучше только в том случае, если мы на первом же сравнении попали в нужный вариант. Если нужный вариант где-то в конце цепочки, то будет как минимум не хуже (особенно если есть несколько строк, начинающихся на одну и ту же букву).
Добавлено через 6 минут rikimaru2013, Ты главное не думай, что это какая-то панацея. Полно вариантов, когда это решение может оказаться хуже, например, тернарного дерева поиска. Думать всегда нужно головой и профилировать
0
|
11.06.2015, 20:38 | 32 | |||||
В твоём случае, все сложные вычисления произойдут в самом начале в любом случае, при чём это не просто пройтись по строке и сравнить каждую букву, в GCC с -O3 на ассемблере вычисление хеша будет выглядеть примерно так:
А вот потом уже: у тебя - результат, не у тебя - посимвольное сравнение оставшихся символов. Так что быстрее, код на ассемблере (который выше), или посимвольное сравнение в конце (что не в твоём коде)? Для меня далеко не очевидно что быстрее твой вариант, даже если это на самом деле так.
1
|
11.06.2015, 20:41 | 33 |
Здесь есть очень важный момент: входная строка должна быть не произвольной, а только одной из 30 допустимых. В противном случае есть риск, что две разные строки могут дать одинаковых хэш-код
Добавлено через 2 минуты Правда ещё надо прикинуть, сколько тактов занимает вычисление хэш-кода. Т.е. выбор между #24 и #26, думается, будет не всегда однозначный и зависит от конкретных значений строковых литералов
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
11.06.2015, 20:46 | 34 |
На коротких примерах не будет видно профита. Можно взять, например, несколько строк, начинающихся одинаково.
Но если для тебя это дело принципа, что ты аж в ассемблер полез, доказать, что код не быстрее, пусть будет так. Мне лень спорить, если честно. На всякий случай, если ты воспринял это как попытку принизить вариант Evg или твой, то ты ошибся. Там об этом написано Можно конечно и добавить дополнительное сравнение со строкой, как в хэш-контейнерах делают.
0
|
11.06.2015, 20:50 | 36 |
Формулировка такая, что для того, кто этого не знает, это далеко не очевидно
Тогда это будет практически однозначно медленнее, чем switch с первой буквой
1
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
11.06.2015, 21:03 | 37 |
Не по теме: Да, слово "лучше" в моей фразе было лишнее. Скажем так, это _иногда_ может быть полезным. Добавлено через 3 минуты В том примере - да. Ты же сам написал Так-то можно придумать пример, где и твой вариант будет очень медленным. Например 30 строк, различающихся только в последних буквах. Единственное, что стоит ТС вынести из нашего разговора, так это то, что нужно думать головой, прежде чем применять тот или иной способ. Добавлено через 6 минут Я имел опыт реального выигрыша от подобной техники в одном из проектов. Я точно знаю, что этот способ имеет право на жизнь (ну возможно не в таком примитивном виде). А то, что всегда можно найти такой набор данных, где какой-либо способ будет очень плох - написано в любом учебнике по алгоритмам. Так что, если ты сейчас докажешь, что на нашем наборе данных (кстати набора-то вроде нет?) этот способ хуже - я не удивлюсь. Если окажется, что они равны или он лучше - ну что ж, бывает.
0
|
12.06.2015, 00:24 | 38 |
Естественно. Тут даже алгоритмом назвать сложно. Попытка решить конкретную проблему для почти конкретных входных данных. Я вот думал, что может быть можно сделать гибрид из двух способов, но толку от этого по ходу не будет. Всегда приходится либо вычислять хэш, либо сравнивать, т.е. где-то сэкономить не получается
Всё равно, когда показаны разные способы и как-то их вслух обсудили - на мой взгляд это помогает лучше прочувствовать ситуацию, чем когда просто дали код и сиди и думай над ним (или тупо передрать) Добавлено через 10 минут Если строки может быть только одной из 30 и никакой другой, то в качестве хэш-функции можно попробовать подогнать что-то типа "str[0] + str[3] - str[2]". Наверняка при некоторой ловкости рук можно получить ну очень короткий вариант и он будет работать с термоядерной скоростью
1
|
12.06.2015, 02:41 | 39 |
Классические решения для мэппинга строк в индекс, это Hash и Trie.
Perfect hash function Trie MARISA: Matching Algorithm with Recursively Implemented StorAge
0
|
12.06.2015, 02:41 | |
12.06.2015, 02:41 | |
Помогаю со студенческими работами здесь
39
Вызов метода объекта для проверки в конструкции switch-case switch case 1 ИЛИ 2 С++, работа с switch case Стек через case в switch Меню через switch и case Работа с оператором Switch case Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |