Re: Померять я завсегда готов :)
От: Sheridan Россия  
Дата: 10.02.12 13:16
Оценка:
Написал на коленке немножко кода для замеров. Меряет в тиках процессора (ну, во всяком случае гугл так говорит).
Методика: берем switch и else if каждого по сотне проверок. Замеряем время отработки цикла из 100000 итераций отдельно для if else, отдельно для switch. И это все замеряем по каждому числу, тоесть обходим каждую ветку ветвления. Выводим результаты по каждому ветвлению и усредненные в конце.
Ну, по коду думается мне будет понятнее...

Для не желающих листать эту простыню — вывод: собирайте с оптимизацией — в этом случае абсолютно без разницы что использовать


Код:
gate ~ # cat ./switch-if.cpp

#include <iostream>
#include <stdlib.h>
using namespace std;
#include <stdint.h>

static inline unsigned long long tick()
{
    unsigned long long d;
    __asm__ __volatile__ ("rdtsc" : "=A" (d) );
    return d;
}


#define SOME return
#define ELSIF(_x) else if (num == _x) { SOME; }
void test_if(int num)
{
    if (num == 0) { SOME; }
    ELSIF(1)  ELSIF(2)  ELSIF(3)  ELSIF(4)  ELSIF(5)  ELSIF(6)  ELSIF(7)  ELSIF(8)  ELSIF(9)  ELSIF(10)
    ELSIF(11) ELSIF(12) ELSIF(13) ELSIF(14) ELSIF(15) ELSIF(16) ELSIF(17) ELSIF(18) ELSIF(19) ELSIF(20)
    ELSIF(21) ELSIF(22) ELSIF(23) ELSIF(24) ELSIF(25) ELSIF(26) ELSIF(27) ELSIF(28) ELSIF(29) ELSIF(30)
    ELSIF(31) ELSIF(32) ELSIF(33) ELSIF(34) ELSIF(35) ELSIF(36) ELSIF(37) ELSIF(38) ELSIF(39) ELSIF(40)
    ELSIF(41) ELSIF(42) ELSIF(43) ELSIF(44) ELSIF(45) ELSIF(46) ELSIF(47) ELSIF(48) ELSIF(49) ELSIF(50)
    ELSIF(51) ELSIF(52) ELSIF(53) ELSIF(54) ELSIF(55) ELSIF(56) ELSIF(57) ELSIF(58) ELSIF(59) ELSIF(60)
    ELSIF(61) ELSIF(62) ELSIF(63) ELSIF(64) ELSIF(65) ELSIF(66) ELSIF(67) ELSIF(68) ELSIF(69) ELSIF(70)
    ELSIF(71) ELSIF(72) ELSIF(73) ELSIF(74) ELSIF(75) ELSIF(76) ELSIF(77) ELSIF(78) ELSIF(79) ELSIF(80)
    ELSIF(81) ELSIF(82) ELSIF(83) ELSIF(84) ELSIF(85) ELSIF(86) ELSIF(87) ELSIF(88) ELSIF(89) ELSIF(90)
    ELSIF(91) ELSIF(92) ELSIF(93) ELSIF(94) ELSIF(95) ELSIF(96) ELSIF(97) ELSIF(98) ELSIF(99)
}

#define SCASE(_x) case _x: { SOME; } break;
void test_switch(int num)
{
    switch (num)
    {
    SCASE(0)
    SCASE(1)  SCASE(2)  SCASE(3)  SCASE(4)  SCASE(5)  SCASE(6)  SCASE(7)  SCASE(8)  SCASE(9)  SCASE(10)
    SCASE(11) SCASE(12) SCASE(13) SCASE(14) SCASE(15) SCASE(16) SCASE(17) SCASE(18) SCASE(19) SCASE(20)
    SCASE(21) SCASE(22) SCASE(23) SCASE(24) SCASE(25) SCASE(26) SCASE(27) SCASE(28) SCASE(29) SCASE(30)
    SCASE(31) SCASE(32) SCASE(33) SCASE(34) SCASE(35) SCASE(36) SCASE(37) SCASE(38) SCASE(39) SCASE(40)
    SCASE(41) SCASE(42) SCASE(43) SCASE(44) SCASE(45) SCASE(46) SCASE(47) SCASE(48) SCASE(49) SCASE(50)
    SCASE(51) SCASE(52) SCASE(53) SCASE(54) SCASE(55) SCASE(56) SCASE(57) SCASE(58) SCASE(59) SCASE(60)
    SCASE(61) SCASE(62) SCASE(63) SCASE(64) SCASE(65) SCASE(66) SCASE(67) SCASE(68) SCASE(69) SCASE(70)
    SCASE(71) SCASE(72) SCASE(73) SCASE(74) SCASE(75) SCASE(76) SCASE(77) SCASE(78) SCASE(79) SCASE(80)
    SCASE(81) SCASE(82) SCASE(83) SCASE(84) SCASE(85) SCASE(86) SCASE(87) SCASE(88) SCASE(89) SCASE(90)
    SCASE(91) SCASE(92) SCASE(93) SCASE(94) SCASE(95) SCASE(96) SCASE(97) SCASE(98) SCASE(99)
    }
}

struct STicksData
{
    unsigned long long ticks_start, ticks_if, ticks_case;
};

#define CYCLE for (unsigned int i = 0; i < 100000; i++)
STicksData test(int num)
{
    STicksData data;
    unsigned long long ticks_start = 0, ticks_if = 0, ticks_case = 0;

    data.ticks_start = tick();
    CYCLE { test_if  (num); }
    data.ticks_if = tick();
    CYCLE { test_switch(num); }
    data.ticks_case = tick();

    cout << "Number:" <<  num                                 << endl;
    cout << "if:    " << (data.ticks_if   - data.ticks_start) << endl;
    cout << "case:  " << (data.ticks_case - data.ticks_if   ) << endl;
//    cout << "Total: " << (data.ticks_case - data.ticks_start) << endl;
    cout << "-------------------------------------"           << endl;
    return data;
}

// -----------------------------------------------------------------------------------------------------------------------------
#define TESTS_COUNT 100
int main ()
{
    STicksData allTicks[TESTS_COUNT];
    for (int i = 0; i<TESTS_COUNT; i++)
    {
        allTicks[i] = test(i);
    }


    unsigned long long average_if = 0, average_switch = 0, average_total = 0;
    for (int i = 0; i<TESTS_COUNT; i++)
    {
        average_if     += (allTicks[i].ticks_if   - allTicks[i].ticks_start);
        average_switch += (allTicks[i].ticks_case - allTicks[i].ticks_if   );
//      average_total  += (allTicks[i].ticks_case - allTicks[i].ticks_start);
    }
    cout << "Average ticks"  << endl;
    cout << "if:    " << (average_if    /TESTS_COUNT) << endl;
    cout << "case:  " << (average_switch/TESTS_COUNT) << endl;
//    cout << "Total: " << (average_total /TESTS_COUNT) << endl;
    return 0;
}


В результатах конечно простыня еще та...
Результаты неоптимизированной сборки:

gate ~ # g++ switch-if.cpp -o si; ./si
Number:0
if:    2434620
case:  2642925
-------------------------------------
Number:1
if:    2088030
case:  2672880
-------------------------------------
Number:2
if:    2221920
case:  2781540
-------------------------------------
Number:3
if:    2421030
case:  2737995
-------------------------------------
Number:4
if:    2621880
case:  2812230
-------------------------------------
Number:5
if:    2822580
case:  2724525
-------------------------------------
Number:6
if:    3030675
case:  2719425
-------------------------------------
Number:7
if:    3156915
case:  2714835
-------------------------------------
Number:8
if:    3438315
case:  2716065
-------------------------------------
Number:9
if:    3638130
case:  2713380
-------------------------------------
Number:10
if:    3832155
case:  2716230
-------------------------------------
Number:11
if:    4246065
case:  2628285
-------------------------------------
Number:12
if:    4452555
case:  2628375
-------------------------------------
Number:13
if:    4457835
case:  2716320
-------------------------------------
Number:14
if:    4687230
case:  2627640
-------------------------------------
Number:15
if:    5183325
case:  2627520
-------------------------------------
Number:16
if:    5231145
case:  2625900
-------------------------------------
Number:17
if:    5642625
case:  2600220
-------------------------------------
Number:18
if:    5947050
case:  2600235
-------------------------------------
Number:19
if:    6234570
case:  2600235
-------------------------------------
Number:20
if:    6528075
case:  2625795
-------------------------------------
Number:21
if:    6482460
case:  2625150
-------------------------------------
Number:22
if:    6846480
case:  2632905
-------------------------------------
Number:23
if:    6941340
case:  2626965
-------------------------------------
Number:24
if:    7362780
case:  2625120
-------------------------------------
Number:25
if:    7341525
case:  2624685
-------------------------------------
Number:26
if:    7762650
case:  2625045
-------------------------------------
Number:27
if:    7940040
case:  2623950
-------------------------------------
Number:28
if:    8163450
case:  2624775
-------------------------------------
Number:29
if:    8169825
case:  2624970
-------------------------------------
Number:30
if:    8566215
case:  2600235
-------------------------------------
Number:31
if:    8739090
case:  2624505
-------------------------------------
Number:32
if:    8981820
case:  2629395
-------------------------------------
Number:33
if:    9057780
case:  2634000
-------------------------------------
Number:34
if:    9332310
case:  2601630
-------------------------------------
Number:35
if:    9412215
case:  2600235
-------------------------------------
Number:36
if:    9776640
case:  2624415
-------------------------------------
Number:37
if:    9779775
case:  2625495
-------------------------------------
Number:38
if:    10179045
case:  2623605
-------------------------------------
Number:39
if:    10201335
case:  2627055
-------------------------------------
Number:40
if:    10572450
case:  2626125
-------------------------------------
Number:41
if:    10625220
case:  2624205
-------------------------------------
Number:42
if:    10915875
case:  2625105
-------------------------------------
Number:43
if:    11056425
case:  2627700
-------------------------------------
Number:44
if:    11360070
case:  2625075
-------------------------------------
Number:45
if:    11415120
case:  2626635
-------------------------------------
Number:46
if:    11805510
case:  2649015
-------------------------------------
Number:47
if:    11999310
case:  2627490
-------------------------------------
Number:48
if:    12197250
case:  2626650
-------------------------------------
Number:49
if:    12147510
case:  2628675
-------------------------------------
Number:50
if:    12508350
case:  2625495
-------------------------------------
Number:51
if:    12546900
case:  2626950
-------------------------------------
Number:52
if:    12904680
case:  2624940
-------------------------------------
Number:53
if:    13033860
case:  2600235
-------------------------------------
Number:54
if:    13378335
case:  2627565
-------------------------------------
Number:55
if:    13298010
case:  2626185
-------------------------------------
Number:56
if:    13750980
case:  2625945
-------------------------------------
Number:57
if:    13661265
case:  2625705
-------------------------------------
Number:58
if:    14171475
case:  2626275
-------------------------------------
Number:59
if:    14284815
case:  2625645
-------------------------------------
Number:60
if:    14571810
case:  2627130
-------------------------------------
Number:61
if:    14485335
case:  2600235
-------------------------------------
Number:62
if:    14965695
case:  2623515
-------------------------------------
Number:63
if:    15233610
case:  2600235
-------------------------------------
Number:64
if:    15269625
case:  2600235
-------------------------------------
Number:65
if:    23596770
case:  2625780
-------------------------------------
Number:66
if:    15780885
case:  2626020
-------------------------------------
Number:67
if:    15831420
case:  2624625
-------------------------------------
Number:68
if:    16075050
case:  2625225
-------------------------------------
Number:69
if:    16204530
case:  2624565
-------------------------------------
Number:70
if:    16496790
case:  2625240
-------------------------------------
Number:71
if:    16668495
case:  2623065
-------------------------------------
Number:72
if:    16877895
case:  2625285
-------------------------------------
Number:73
if:    17105505
case:  2630115
-------------------------------------
Number:74
if:    17321640
case:  2624715
-------------------------------------
Number:75
if:    17563830
case:  2622690
-------------------------------------
Number:76
if:    17705850
case:  2623290
-------------------------------------
Number:77
if:    17793165
case:  2625090
-------------------------------------
Number:78
if:    18034365
case:  2625600
-------------------------------------
Number:79
if:    18388860
case:  2624595
-------------------------------------
Number:80
if:    18570120
case:  2601345
-------------------------------------
Number:81
if:    18635235
case:  2601525
-------------------------------------
Number:82
if:    18882225
case:  2625735
-------------------------------------
Number:83
if:    19041840
case:  2631060
-------------------------------------
Number:84
if:    19344630
case:  2625105
-------------------------------------
Number:85
if:    19434015
case:  2626845
-------------------------------------
Number:86
if:    19756770
case:  2625960
-------------------------------------
Number:87
if:    19816695
case:  2627760
-------------------------------------
Number:88
if:    20121810
case:  2628255
-------------------------------------
Number:89
if:    20227305
case:  2627610
-------------------------------------
Number:90
if:    20515200
case:  2623455
-------------------------------------
Number:91
if:    22120935
case:  2629860
-------------------------------------
Number:92
if:    20968785
case:  2625945
-------------------------------------
Number:93
if:    21100155
case:  2625705
-------------------------------------
Number:94
if:    21419655
case:  2624250
-------------------------------------
Number:95
if:    21858960
case:  2624640
-------------------------------------
Number:96
if:    21814755
case:  2623080
-------------------------------------
Number:97
if:    21769530
case:  2624640
-------------------------------------
Number:98
if:    22225110
case:  2625105
-------------------------------------
Number:99
if:    22131165
case:  2625195
-------------------------------------
Average ticks
if:    12387129
case:  2634786

Как видите — вариант с if практически сразу потерял свои позиции и под конец разница с switch на порядок.

А вот результаты сборки с оптимизацией мгновенно ставят все на свои места
gate ~ # g++ switch-if.cpp -O2 -o si; ./si
Number:0
if:    105
case:  90
-------------------------------------
Number:1
if:    105
case:  105
-------------------------------------
Number:2
if:    120
case:  105
-------------------------------------
Number:3
if:    120
case:  105
-------------------------------------
Number:4
if:    105
case:  105
-------------------------------------
Number:5
if:    120
case:  105
-------------------------------------
Number:6
if:    105
case:  105
-------------------------------------
Number:7
if:    105
case:  105
-------------------------------------
Number:8
if:    105
case:  105
-------------------------------------
Number:9
if:    105
case:  105
-------------------------------------
Number:10
if:    105
case:  105
-------------------------------------
Number:11
if:    105
case:  90
-------------------------------------
Number:12
if:    120
case:  105
-------------------------------------
Number:13
if:    105
case:  120
-------------------------------------
Number:14
if:    105
case:  105
-------------------------------------
Number:15
if:    105
case:  105
-------------------------------------
Number:16
if:    120
case:  105
-------------------------------------
Number:17
if:    105
case:  105
-------------------------------------
Number:18
if:    105
case:  105
-------------------------------------
Number:19
if:    105
case:  120
-------------------------------------
Number:20
if:    105
case:  90
-------------------------------------
Number:21
if:    105
case:  120
-------------------------------------
Number:22
if:    90
case:  120
-------------------------------------
Number:23
if:    105
case:  105
-------------------------------------
Number:24
if:    105
case:  105
-------------------------------------
Number:25
if:    120
case:  105
-------------------------------------
Number:26
if:    105
case:  120
-------------------------------------
Number:27
if:    90
case:  105
-------------------------------------
Number:28
if:    105
case:  105
-------------------------------------
Number:29
if:    120
case:  120
-------------------------------------
Number:30
if:    105
case:  120
-------------------------------------
Number:31
if:    105
case:  120
-------------------------------------
Number:32
if:    105
case:  120
-------------------------------------
Number:33
if:    105
case:  105
-------------------------------------
Number:34
if:    105
case:  105
-------------------------------------
Number:35
if:    105
case:  105
-------------------------------------
Number:36
if:    105
case:  105
-------------------------------------
Number:37
if:    105
case:  105
-------------------------------------
Number:38
if:    105
case:  105
-------------------------------------
Number:39
if:    105
case:  105
-------------------------------------
Number:40
if:    105
case:  105
-------------------------------------
Number:41
if:    105
case:  105
-------------------------------------
Number:42
if:    105
case:  105
-------------------------------------
Number:43
if:    105
case:  105
-------------------------------------
Number:44
if:    105
case:  105
-------------------------------------
Number:45
if:    105
case:  90
-------------------------------------
Number:46
if:    105
case:  105
-------------------------------------
Number:47
if:    120
case:  90
-------------------------------------
Number:48
if:    105
case:  105
-------------------------------------
Number:49
if:    105
case:  105
-------------------------------------
Number:50
if:    105
case:  105
-------------------------------------
Number:51
if:    105
case:  120
-------------------------------------
Number:52
if:    120
case:  105
-------------------------------------
Number:53
if:    105
case:  105
-------------------------------------
Number:54
if:    105
case:  105
-------------------------------------
Number:55
if:    120
case:  105
-------------------------------------
Number:56
if:    105
case:  105
-------------------------------------
Number:57
if:    105
case:  105
-------------------------------------
Number:58
if:    120
case:  105
-------------------------------------
Number:59
if:    105
case:  105
-------------------------------------
Number:60
if:    105
case:  105
-------------------------------------
Number:61
if:    105
case:  105
-------------------------------------
Number:62
if:    120
case:  105
-------------------------------------
Number:63
if:    105
case:  120
-------------------------------------
Number:64
if:    120
case:  105
-------------------------------------
Number:65
if:    105
case:  105
-------------------------------------
Number:66
if:    105
case:  105
-------------------------------------
Number:67
if:    105
case:  120
-------------------------------------
Number:68
if:    105
case:  105
-------------------------------------
Number:69
if:    120
case:  90
-------------------------------------
Number:70
if:    105
case:  105
-------------------------------------
Number:71
if:    105
case:  105
-------------------------------------
Number:72
if:    105
case:  105
-------------------------------------
Number:73
if:    105
case:  120
-------------------------------------
Number:74
if:    120
case:  105
-------------------------------------
Number:75
if:    105
case:  120
-------------------------------------
Number:76
if:    90
case:  105
-------------------------------------
Number:77
if:    105
case:  105
-------------------------------------
Number:78
if:    105
case:  105
-------------------------------------
Number:79
if:    105
case:  105
-------------------------------------
Number:80
if:    120
case:  105
-------------------------------------
Number:81
if:    105
case:  105
-------------------------------------
Number:82
if:    120
case:  105
-------------------------------------
Number:83
if:    105
case:  105
-------------------------------------
Number:84
if:    120
case:  90
-------------------------------------
Number:85
if:    105
case:  105
-------------------------------------
Number:86
if:    105
case:  120
-------------------------------------
Number:87
if:    120
case:  90
-------------------------------------
Number:88
if:    105
case:  105
-------------------------------------
Number:89
if:    120
case:  105
-------------------------------------
Number:90
if:    105
case:  120
-------------------------------------
Number:91
if:    120
case:  105
-------------------------------------
Number:92
if:    120
case:  90
-------------------------------------
Number:93
if:    105
case:  120
-------------------------------------
Number:94
if:    105
case:  105
-------------------------------------
Number:95
if:    105
case:  105
-------------------------------------
Number:96
if:    105
case:  105
-------------------------------------
Number:97
if:    105
case:  105
-------------------------------------
Number:98
if:    105
case:  105
-------------------------------------
Number:99
if:    105
case:  120
-------------------------------------
Average ticks
if:    107
case:  106
Matrix has you...