Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/125: Рейтинг темы: голосов - 125, средняя оценка - 4.73
3 / 3 / 4
Регистрация: 23.06.2014
Сообщений: 126

If или switch().case. Что быстрее

07.07.2014, 10:22. Показов 24039. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть два кода. Первый:
C++
1
2
3
4
5
6
if(a == 2)
a += 2;
if(a == 3)
a+= 3;
if(a == 4)
a+=4;
Второй:
C++
1
2
3
4
5
6
switch(a)
}
case 2: a += 2; break;
case 3: a+= 3; break;
case 4: a += 4; break;
}
Эти коды одинаковы по своим функциям, но какой же из них будет работать быстрее?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.07.2014, 10:22
Ответы с готовыми решениями:

switch case 1 ИЛИ 2
делаю разбор вводимых команд, некоторые обрабатываются похоже, команды однобуквенные, разбираю кейсом, но вот как сделать чтобы 1 блок...

case outside of switch ? Что за ошибка?
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #pragma argsused ...

Что делают операторы switch/case
что делают функции : switch ? case ?

27
Модератор
Эксперт С++
 Аватар для zss
13769 / 10962 / 6491
Регистрация: 18.12.2011
Сообщений: 29,236
07.07.2014, 10:24
Скорее всего, разницы в скорости Вы не заметите.
Однако, второй код более нагляден.
1
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
07.07.2014, 10:36
Цитата Сообщение от mihalech19 Посмотреть сообщение
Эти коды одинаковы по своим функциям
нет
Цитата Сообщение от mihalech19 Посмотреть сообщение
но какой же из них будет работать быстрее
свитч вроде в в ифы разворачивается, нэ?
1
 Аватар для IrineK
2023 / 1641 / 425
Регистрация: 23.02.2011
Сообщений: 6,002
Записей в блоге: 25
07.07.2014, 10:37
Лучший ответ Сообщение было отмечено mihalech19 как решение

Решение

В первом случае все if будут проверяться всегда.

Во втором случае все case будут пройдены только при а = 4. Например, если а = 2, то отработает только первый case и мы выйдем по break. При а = 3 отработают два первых case.

В среднем - второй случай быстрей.
2
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.07.2014, 10:37
Лучший ответ Сообщение было отмечено Kastaneda как решение

Решение

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

Ну и каждое ветвление награждает вас 50% бонусом к шансу получить неверным предсказанием перехода по башке. Что не лучшим образом сказывается на производительности. Поэтому лучше их без нужды не плодить.
2
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
07.07.2014, 10:41
Цитата Сообщение от IrineK Посмотреть сообщение
При а = 3 отработают два первых case.
это почему?
1
 Аватар для IrineK
2023 / 1641 / 425
Регистрация: 23.02.2011
Сообщений: 6,002
Записей в блоге: 25
07.07.2014, 10:45
Цитата Сообщение от Kukurudza Посмотреть сообщение
это почему?
Цитата Сообщение от Kukurudza Посмотреть сообщение
свитч вроде в в ифы разворачивается
И else.
2
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
07.07.2014, 10:47
А, чьёрт действительно.
1
Модератор
Эксперт С++
 Аватар для zss
13769 / 10962 / 6491
Регистрация: 18.12.2011
Сообщений: 29,236
07.07.2014, 11:18
Кстати, не так-то просто иногда развернуть в if, например:
C++
1
2
3
4
5
6
7
8
9
int a=0;
int m;cin>>m;
switch(m)
{
case 1:
    a=2;
case 2:
    a++;
}
C++
1
2
3
4
5
6
if(m==1)
{      
     a=2;
     a++;
}else if(m==2)
     a++;
8 строку пришлось продублировать
0
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
07.07.2014, 11:21
кейсы без брейков жесть какая-та имхо
0
Модератор
Эксперт С++
 Аватар для zss
13769 / 10962 / 6491
Регистрация: 18.12.2011
Сообщений: 29,236
07.07.2014, 11:34
Цитата Сообщение от Kukurudza Посмотреть сообщение
жесть какая-та
Иногда очень даже удобно. Только настоятельно рекомендуется это место комментировать:
C++
1
2
3
4
5
6
7
8
switch(m)
{
case 1:
    a=2;
// брейк не нужен (проваливаемся дальше)
case 2:
    a++;
}
1
 Аватар для palva
4272 / 2966 / 691
Регистрация: 08.06.2007
Сообщений: 9,915
Записей в блоге: 4
07.07.2014, 11:52
Все промышленные компиляторы имеют мощный оптимизатор, который нивелирует любые ухищрения программиста сделать код эффективнее. Реально влиять на эффективность можно, если вы пишете на ассемблере. А на языке высокого уровня лучше обращать внимание на прозрачность кода, на соответствие его корпоративным стандартам и на облегчение сопровождения. Об эффективности нужно думать на этапе архитектурного проектирования. А когда дело дошло до языка си, то простое наличие комментариев важнее эффективности.
1
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
07.07.2014, 11:54
Цитата Сообщение от palva Посмотреть сообщение
который нивелирует любые ухищрения программиста сделать код эффективнее.
из практики например развертка циклов (два вложенных друг в друга) дала ощутимый результат. переводил из RGB в YUV.
1
0 / 0 / 0
Регистрация: 02.07.2014
Сообщений: 6
07.07.2014, 15:34
в данном случае разницы никакой для человеческого восприятия скорости, однако теоретически кейс быстрее
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2773 / 491
Регистрация: 28.04.2012
Сообщений: 8,760
07.07.2014, 17:49
Цитата Сообщение от zss Посмотреть сообщение
Иногда очень даже удобно. Только настоятельно рекомендуется это место комментировать:
Вот из-за этих "иногда" и "настоятельно рекомендуется это место комментировать" лучше бы был неявный break и явный fallthroug.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
07.07.2014, 18:30
Цитата Сообщение от Kukurudza Посмотреть сообщение
кейсы без брейков жесть какая-та имхо
Это ты еще duff device не видел

------
А вообще все эти рассуждения о скорости не имеют смысла без привязки к конкретному компилятору и его оптимизации. Если хочется адекватных оценок, то берем компилятор, конкретные ключи компиляции, смотрим ассемблер и делаем выводы. Все остальное от лукавого.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
07.07.2014, 18:48
Цитата Сообщение от mihalech19 Посмотреть сообщение
Эти коды одинаковы по своим функциям,
фиг вам посмотри что будет если во первом коде
a изначальна равна 2 в результате она будет равна 8
чего не наблюдается во втором коде
Цитата Сообщение от Kukurudza Посмотреть сообщение
свитч вроде в в ифы разворачивается, нэ?
при очень разреженном
при case 0 1 2 3 4
скорее всего switch превратится в таблицу переходов
у Evg в блоге была статья на эту тему
если найду кину ссылку

Добавлено через 1 минуту
Цитата Сообщение от Kukurudza Посмотреть сообщение
кейсы без брейков жесть какая-та имхо
очень даже распространенная практика "проваливания"
кстати в шарпе её кастрировали и приходится дублировать код

Добавлено через 3 минуты
вот ссылка
https://www.cyberforum.ru/blogs/18334/blog91.html
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
07.07.2014, 18:49
Цитата Сообщение от ValeryS Посмотреть сообщение
очень даже распространенная практика "проваливания"
согласен, чаще всего приходится встречать такое
C++
1
2
3
4
5
6
case 1: 
case 2:
case 3:
case 4:
    // code
    break;
в gcc добавили удобную фишку Case Ranges, можно писать так
C++
1
2
3
4
5
6
case 1 ... 4:
    // code
 
// и даже так
case 'a' ... 'z' :
    // code
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
07.07.2014, 18:55
Цитата Сообщение от Kastaneda Посмотреть сообщение
чаще всего приходится встречать такое
чаще да
но посмотри на код по ссылке

Напоследок хочется сказать, что на практике такими "дебильными" конструкциями пользуются очень и очень редко. На практике я пока только однажды встречал конструкцию, являющуюся вариацией алгоритма под названием Duff's device
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void send (int *to, const int *from, int count)
{
  int n = (count + 7) / 8;
  swith (count % 8)
  {
    case 0: do { *to++ = *from++;
    case 7:      *to++ = *from++;
    case 6:      *to++ = *from++;
    case 5:      *to++ = *from++;
    case 4:      *to++ = *from++;
    case 3:      *to++ = *from++;
    case 2:      *to++ = *from++;
    case 1:      *to++ = *from++;
            } while (--n > 0);
  }
}
кстати обсуждалась здесь
Что делает данный код и зачем такое кому-нибудь может понадобиться?

Добавлено через 2 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
в gcc добавили удобную фишку Case Ranges, можно писать так
а если нужно вот так
C++
1
2
3
4
5
switch(n)
 {
   case 5:
   case 10:
   case 15:
то "фишкой" уже не обойдешься
0
 Аватар для RaiaNKnight
97 / 71 / 12
Регистрация: 29.06.2011
Сообщений: 465
Записей в блоге: 1
07.07.2014, 19:00
Ещё неплохой способ "we need to go deeper":

Юзаем switch-case:
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
movl    $4, -4(%rbp)      // int a = 4;
 
movl    -4(%rbp), %eax  //switch begin
cmpl    $3, %eax
je  .L3
cmpl    $4, %eax
je  .L4
cmpl    $2, %eax
jne .L2                   //switch end
 
addl    $2, -4(%rbp)     //1-й case
jmp .L2
                .L3:
addl    $3, -4(%rbp)     //2-й case
jmp .L2
                .L4:     
addl    $4, -4(%rbp)     //3-й case
nop
                .L2:
...


Юзаем if'ы:
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
movl    $4, -4(%rbp)   // int a = 4;
 
cmpl    $2, -4(%rbp)   //1-й if begin
jne .L2
addl    $2, -4(%rbp)   //1-й if end
 
                .L2:
cmpl    $3, -4(%rbp)   //2-й if begin
jne .L3
addl    $3, -4(%rbp)   //2-й if end
 
                .L3:
cmpl    $4, -4(%rbp)   //3-й if begin
jne .L4
addl    $4, -4(%rbp)   //3-й if end


Компилятор GNU GCC C++ .

Особо разницы не заметите, разве что во 1-м случае используются прыжки je, а во 2-м - jne.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.07.2014, 19:00
Помогаю со студенческими работами здесь

Оптимальная конструкция switch-case-while / while-switch-case
Имеется конструкция типа: switch() { case 1: while() { ... }

Статический хеш или switch-case/if-else для выбора
Добрый день. Положим есть такой код:void parseByType(const QString &data, const QString &type) { if(type == "integer") ...

if или switch? что быстрее
Здравствуйте. Подскажите пожалуйста,что быстрее будет выполняться много условий if ,или switch int z = 5; if (z==4) z= 3; if...

Что быстрее switch(enum) или if else?
Может кто нибудь знает,какая конструкция лучше в плане производительности: 1) enum e{one, two, three}; switch (e) { case.. ...

Что быстрее, вложенные REPLACE или функция с CASE на va?
Здравствуйте форумчане. Имеется база с приличным количеством записей, порядка миллиона. Задача в запросе вывести значение одного из полей...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru