Сравнение скорости if и switch
От: Аноним  
Дата: 05.02.12 15:21
Оценка:
Приветствую.

А что, switch действительно выигрывает в скорости по сравнению с конструкциями if — else, если значения в нём последовательные?

Например, есть примерно след. участок кода:

enum {a, b, c, d, e};

int value;

...

void f ()
{
    ...
    if (value == a)
    {
        ...
    }
    else if (value == b)
    {
        ...
    }
    else if (value == c)
    {
        ...
    }
    else if (value == d)
    {
        ...
    }
    else if (value == e)
    {
        ...
    }
    ...
}



Вызов данной функции происходит довольно часто, поэтому интересует, будет ли хоть какой-то полезный выигрыш от использования switch в данном случае?

Не оптимизирует ли всё это дело компилятор так, что выйдет либо одинаковая производительность, либо даже хуже?

Использую MS-компилятор.
Re: Сравнение скорости if и switch
От: LaptevVV Россия  
Дата: 05.02.12 15:31
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:
А>А что, switch действительно выигрывает в скорости по сравнению с конструкциями if — else, если значения в нём последовательные?
А>Не оптимизирует ли всё это дело компилятор так, что выйдет либо одинаковая производительность, либо даже хуже?
А>Использую MS-компилятор.
Ну так проверить что мешает?
Либо с помощью профайлера, либо ручками в лоб получить время выполнения.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Сравнение скорости if и switch
От: potapov.d  
Дата: 05.02.12 15:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Приветствую.


А>А что, switch действительно выигрывает в скорости по сравнению с конструкциями if — else, если значения в нём последовательные?


А>Например, есть примерно след. участок кода:


А>
А>enum {a, b, c, d, e};

А>int value;

А>...

А>void f ()
А>{
А>    ...
А>    if (value == a)
А>    {
А>        ...
А>    }
А>    else if (value == b)
А>    {
А>        ...
А>    }
А>    else if (value == c)
А>    {
А>        ...
А>    }
А>    else if (value == d)
А>    {
А>        ...
А>    }
А>    else if (value == e)
А>    {
А>        ...
А>    }
А>    ...
А>}
А>


лет пять назад дизассемблировал подобный сниппет. в Release сборке студия данную последовательность if'ов преобразует в switch. (его ассемблерное представление, разумеется)
Re: Сравнение скорости if и switch
От: lastcross  
Дата: 08.02.12 12:03
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Приветствую.


А>А что, switch действительно выигрывает в скорости по сравнению с конструкциями if — else, если значения в нём последовательные?


А>Например, есть примерно след. участок кода:


А>
А>enum {a, b, c, d, e};

А>int value;

А>...

А>void f ()
А>{
А>    ...
А>    if (value == a)
А>    {
А>        ...
А>    }
А>    else if (value == b)
А>    {
А>        ...
А>    }
А>    else if (value == c)
А>    {
А>        ...
А>    }
А>    else if (value == d)
А>    {
А>        ...
А>    }
А>    else if (value == e)
А>    {
А>        ...
А>    }
А>    ...
А>}
А>



А>Вызов данной функции происходит довольно часто, поэтому интересует, будет ли хоть какой-то полезный выигрыш от использования switch в данном случае?


А>Не оптимизирует ли всё это дело компилятор так, что выйдет либо одинаковая производительность, либо даже хуже?


А>Использую MS-компилятор.


Помнится даже на баше был гдето ответ. Тут чтоле
Re: Сравнение скорости if и switch
От: watch-maker  
Дата: 08.02.12 12:36
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Приветствую.


А>А что, switch действительно выигрывает в скорости по сравнению с конструкциями if — else, если значения в нём последовательные?

А>Вызов данной функции происходит довольно часто, поэтому интересует, будет ли хоть какой-то полезный выигрыш от использования switch в данном случае?

Это существенно зависит от распределения значений входных данных. Если какой-либо зависимости в значениях value нет, то switch вполне может быть лучшим вариантом. Если же значение a или b встречаются значительно чаще (например в 95% и 4% случаев соответственно), то if может существенно превосходить в скорости switch.
Это связано с особенностью блока предсказания ветвлений процессора. Последовательные if позволяют ему «обучаться» на входных данных и лучше предсказывать нужную ветку программы. В то же время switch, если компилятор сделал из него таблицу и косвенный переход, будет справляться с этой задачей значительно хуже.
Например, для архитектур x86 и x86-64 подробнее об switch-против-if можно прочитать в «Intel® 64 and IA-32 Architectures Optimization Reference Manual».
Ну и вообще, в таких случаях может быть эффективна гибридная схема:
void f ()
{
    if (value == a) // отдельно обрабатываем вероятное значение
        ...
    else if (value == b) // отдельно обрабатываем вероятное значение
        ...
    else switch (value) { // обрабатываем всё остальное
        case c: ...
        case d: ...
    }
}

Для уверенности, что компилятор нас правильно понял, ещё бывает полезно обернуть условие (value == a) во что-то подобное __builtin_expect(value == a, 1) или __assume(value == a). Где __builtin_expect и __assume — соответствующие подсказки оптимизатору.


А>Не оптимизирует ли всё это дело компилятор так, что выйдет либо одинаковая производительность, либо даже хуже?


Универсального ответа тут нет. Но что тебе мешает просто посмотреть сгенерированный код самому? Для того, чтобы сказать, что получился одинаковый код, можно же даже не знать ассемблера.
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...
Re[2]: Померять я завсегда готов :)
От: Сыроежка  
Дата: 10.02.12 13:23
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Написал на коленке немножко кода для замеров. Меряет в тиках процессора (ну, во всяком случае гугл так говорит).


На мой взгляд это совершенно бессмиысленное заниятие. Во-первых, часто компилятор для двух конструкций генерирует один и тот же ассемблерный код, если конструкции не сложные. Во-вторых, не каждый if можно заменить предложением switch. И, в-третьих, скорость ни одной программы не страдает от того, используете ли вы if или swicth.
Меня можно встретить на www.cpp.forum24.ru
Re[3]: Померять я завсегда готов :)
От: Sheridan Россия  
Дата: 10.02.12 13:28
Оценка:
Здравствуйте, Сыроежка, Вы писали:

С>На мой взгляд это совершенно бессмиысленное заниятие. Во-первых, часто компилятор для двух конструкций генерирует один и тот же ассемблерный код, если конструкции не сложные. Во-вторых, не каждый if можно заменить предложением switch. И, в-третьих, скорость ни одной программы не страдает от того, используете ли вы if или swicth.


Ребе, ну человек задал конкретный вопрос — я на него дал не просто ответ, а вполне себе даже исследование.
С написанными тобой буквами я то согласен и так. Только вот было интересно их както подтвердить
Подтвердил таки?
Matrix has you...
Re[2]: Померять я завсегда готов :)
От: watch-maker  
Дата: 10.02.12 13:46
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Написал на коленке немножко кода для замеров. Меряет в тиках процессора (ну, во всяком случае гугл так говорит).

S>Методика: берем switch и else if каждого по сотне проверок. Замеряем время отработки цикла из 100000 итераций отдельно для if else, отдельно для switch. И это все замеряем по каждому числу, тоесть обходим каждую ветку ветвления. Выводим результаты по каждому ветвлению и усредненные в конце.
S>Ну, по коду думается мне будет понятнее...

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


Тест плохой.
Например, gcc43 просто преобразует функцию test_if в такую:
void test_if(int num) {
   return;
}

Вы сравнили скорость работы двух пустых функций.
Re[2]: Померять я завсегда готов :)
От: batu Украина  
Дата: 10.02.12 14:08
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Написал на коленке немножко кода для замеров. Меряет в тиках процессора (ну, во всяком случае гугл так говорит).

S>Методика: берем switch и else if каждого по сотне проверок. Замеряем время отработки цикла из 100000 итераций отдельно для if else, отдельно для switch. И это все замеряем по каждому числу, тоесть обходим каждую ветку ветвления. Выводим результаты по каждому ветвлению и усредненные в конце.
S>Ну, по коду думается мне будет понятнее...

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


Собственно результат был прогнозируемый. Так и мозги выключать никто не заставляет когда пишешь. Есть два оператора и нужно думать когда и какой применять. С case выглядит более наглядно и легко добавить если нужда возникнет. Но я хотел не об этом. В своем языке придумал еще один оператор. Первый типа swith создает переменную -переключатель перечислимого типа (допустим S) с необязательным присваиванием имени-значения для каждого варианта условия, а второй (Execute S) выполняет переход по этой переменной. Это выгодно когда после проверки необходимо выполнить какую то общую часть для всех вариантов переключателя, а в другом месте выполнить разные участки программы в зависимости от значения переключателя. Причем оператор Execute можно несколько раз применить.
Re[4]: Померять я завсегда готов :)
От: batu Украина  
Дата: 10.02.12 14:10
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Здравствуйте, Сыроежка, Вы писали:


С>>На мой взгляд это совершенно бессмиысленное заниятие. Во-первых, часто компилятор для двух конструкций генерирует один и тот же ассемблерный код, если конструкции не сложные. Во-вторых, не каждый if можно заменить предложением switch. И, в-третьих, скорость ни одной программы не страдает от того, используете ли вы if или swicth.


S>Ребе, ну человек задал конкретный вопрос — я на него дал не просто ответ, а вполне себе даже исследование.

S>С написанными тобой буквами я то согласен и так. Только вот было интересно их както подтвердить
S>Подтвердил таки?
Мне кажется не только подтвердил, но и указал разницу.
Re[3]: Померять я завсегда готов :)
От: Sheridan Россия  
Дата: 10.02.12 15:51
Оценка:
Здравствуйте, watch-maker, Вы писали:

WM>Например, gcc43 просто преобразует функцию test_if в такую:

WM>Вы сравнили скорость работы двух пустых функций.
Я пока ехал домой — это понял. Как раз собрался переделывать
Matrix has you...
Re[2]: Обломатушки, ну почти.
От: Sheridan Россия  
Дата: 10.02.12 16:29
Оценка:
Как справедливо было замечено
Автор: watch-maker
Дата: 10.02.12
— оптимизатор г++ слишком хорош для данного случая, а я писал на работе, слишком хотел домой и не подумал об этом. Посыпаю голову пеплом, и все такое.
В общем я нагрузил алгоритм еще одной функцией, которая принимает в себя число-счетчик цикла и на его основе считает всякую фигню. Ну типа полезную работу делает.
Также я на отдельно замеряю среднее количество тиков работы этой функции и вычитаю это потом из результата.

Кратко — результаты без оптимизации и с -O2 практически выровнялись. Разница приблизительно в 1,3 раза, switch выигрывает.
Но вот, сюрприз, с -O3 switch внезапно начинает обходить if на два порядка.

Код:

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

#define TESTS_COUNT 100
#define SOME somework(num)
#define ELSIF(_x) else if (num == _x) { SOME; }
#define SCASE(_x) case _x: { SOME; } break;
#define CYCLE(_type, _count) for (_type i = 0; i < _count; i++)
#define LONG_CYCLE CYCLE(unsigned long long, TESTS_COUNT*TESTS_COUNT*TESTS_COUNT)
#define TESTS_COUNT_CYCLE CYCLE(int, TESTS_COUNT)

unsigned long long somewariable = 0;

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

void somework(int num)
{
    int a = sin(num);
    somewariable = cos(a+++num);
}

unsigned long long someworkTicks()
{
    unsigned long long ticks_start, ticks_end;
    ticks_start = tick();
    TESTS_COUNT_CYCLE { somework(i); }
    ticks_end = tick();
    return (ticks_end - ticks_start)/TESTS_COUNT;
}


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)
}


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;
};


STicksData test(int num, unsigned long long st)
{
    STicksData data;

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

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

// -----------------------------------------------------------------------------------------------------------------------------
int main ()
{
    unsigned long long st = someworkTicks();
    STicksData allTicks[TESTS_COUNT];
    TESTS_COUNT_CYCLE
    {
        allTicks[i] = test(i, st);
    }


    unsigned long long average_if = 0, average_switch = 0, average_total = 0;
    TESTS_COUNT_CYCLE
    {
        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;
}


Результат без оптимизаций
sheridan@amd-gentoo tests % g++ if-case.cpp -o si; ./si
Number: 0; if: 5231; case: 6546; 
Number: 1; if: 24566; case: 22647; 
Number: 2; if: 23597; case: 22243; 
Number: 3; if: 31683; case: 29458; 
Number: 4; if: 51127; case: 29016; 
Number: 5; if: 31886; case: 29061; 
Number: 6; if: 31513; case: 28714; 
Number: 7; if: 31786; case: 28620; 
Number: 8; if: 31776; case: 28919; 
Number: 9; if: 31904; case: 29244; 
Number: 10; if: 32425; case: 29664; 
Number: 11; if: 31117; case: 28366; 
Number: 12; if: 32097; case: 28867; 
Number: 13; if: 31611; case: 28141; 
Number: 14; if: 33479; case: 29676; 
Number: 15; if: 33580; case: 29522; 
Number: 16; if: 50382; case: 29407; 
Number: 17; if: 33329; case: 29133; 
Number: 18; if: 33596; case: 29043; 
Number: 19; if: 39218; case: 34562; 
Number: 20; if: 34180; case: 28986; 
Number: 21; if: 34255; case: 29009; 
Number: 22; if: 33630; case: 27863; 
Number: 23; if: 35377; case: 29243; 
Number: 24; if: 34797; case: 29131; 
Number: 25; if: 35607; case: 28884; 
Number: 26; if: 36327; case: 29578; 
Number: 27; if: 35423; case: 29065; 
Number: 28; if: 36542; case: 29335; 
Number: 29; if: 36879; case: 29490; 
Number: 30; if: 35878; case: 29060; 
Number: 31; if: 36646; case: 28718; 
Number: 32; if: 36722; case: 29118; 
Number: 33; if: 35970; case: 28095; 
Number: 34; if: 37538; case: 29156; 
Number: 35; if: 38570; case: 29495; 
Number: 36; if: 38164; case: 29271; 
Number: 37; if: 37878; case: 28412; 
Number: 38; if: 38150; case: 29236; 
Number: 39; if: 56391; case: 29382; 
Number: 40; if: 38712; case: 28866; 
Number: 41; if: 39742; case: 29639; 
Number: 42; if: 39191; case: 29015; 
Number: 43; if: 38907; case: 28566; 
Number: 44; if: 39041; case: 28056; 
Number: 45; if: 40340; case: 28621; 
Number: 46; if: 40109; case: 28942; 
Number: 47; if: 39556; case: 28217; 
Number: 48; if: 40690; case: 29233; 
Number: 49; if: 40788; case: 44688; 
Number: 50; if: 41130; case: 28763; 
Number: 51; if: 41332; case: 28204; 
Number: 52; if: 41438; case: 29065; 
Number: 53; if: 42243; case: 29456; 
Number: 54; if: 43001; case: 29435; 
Number: 55; if: 41579; case: 28384; 
Number: 56; if: 42199; case: 28714; 
Number: 57; if: 42592; case: 28779; 
Number: 58; if: 42065; case: 28445; 
Number: 59; if: 43884; case: 29505; 
Number: 60; if: 60339; case: 29813; 
Number: 61; if: 43706; case: 28976; 
Number: 62; if: 48062; case: 32434; 
Number: 63; if: 43802; case: 28126; 
Number: 64; if: 45031; case: 29376; 
Number: 65; if: 48779; case: 33106; 
Number: 66; if: 43914; case: 28312; 
Number: 67; if: 45479; case: 29204; 
Number: 68; if: 45589; case: 28597; 
Number: 69; if: 44685; case: 28006; 
Number: 70; if: 63052; case: 29261; 
Number: 71; if: 46060; case: 28876; 
Number: 72; if: 46894; case: 29504; 
Number: 73; if: 47547; case: 29568; 
Number: 74; if: 46261; case: 29076; 
Number: 75; if: 47006; case: 28954; 
Number: 76; if: 47176; case: 28883; 
Number: 77; if: 46175; case: 28063; 
Number: 78; if: 47973; case: 28995; 
Number: 79; if: 48552; case: 29471; 
Number: 80; if: 63565; case: 28460; 
Number: 81; if: 48263; case: 28755; 
Number: 82; if: 48757; case: 28686; 
Number: 83; if: 58056; case: 39099; 
Number: 84; if: 49034; case: 29012; 
Number: 85; if: 49800; case: 29524; 
Number: 86; if: 49821; case: 29114; 
Number: 87; if: 49565; case: 29174; 
Number: 88; if: 49211; case: 28151; 
Number: 89; if: 50038; case: 46191; 
Number: 90; if: 51031; case: 29290; 
Number: 91; if: 49965; case: 28308; 
Number: 92; if: 50858; case: 28995; 
Number: 93; if: 50861; case: 29106; 
Number: 94; if: 51611; case: 28811; 
Number: 95; if: 51044; case: 28643; 
Number: 96; if: 51846; case: 28945; 
Number: 97; if: 52293; case: 29051; 
Number: 98; if: 52979; case: 29463; 
Number: 99; if: 68037; case: 28276; 
Average ticks
if:    42928
case:  29964


и результат с оптимизациями

sheridan@amd-gentoo tests % g++ if-case.cpp -O2 -o si; ./si
Number: 0; if: 4209; case: 3988; 
Number: 1; if: 23017; case: 20805; 
Number: 2; if: 22176; case: 21267; 
Number: 3; if: 29033; case: 27017; 
Number: 4; if: 28951; case: 26887; 
Number: 5; if: 29551; case: 26269; 
Number: 6; if: 29417; case: 26552; 
Number: 7; if: 30218; case: 26902; 
Number: 8; if: 30245; case: 27421; 
Number: 9; if: 30333; case: 26417; 
Number: 10; if: 30684; case: 27439; 
Number: 11; if: 29689; case: 25796; 
Number: 12; if: 30690; case: 26389; 
Number: 13; if: 30716; case: 26126; 
Number: 14; if: 30436; case: 26980; 
Number: 15; if: 31014; case: 27260; 
Number: 16; if: 31928; case: 27430; 
Number: 17; if: 31167; case: 27161; 
Number: 18; if: 31588; case: 26756; 
Number: 19; if: 37303; case: 32483; 
Number: 20; if: 32075; case: 26611; 
Number: 21; if: 32329; case: 27356; 
Number: 22; if: 31538; case: 25823; 
Number: 23; if: 33278; case: 26851; 
Number: 24; if: 32300; case: 26452; 
Number: 25; if: 32848; case: 26228; 
Number: 26; if: 32981; case: 52079; 
Number: 27; if: 32921; case: 27266; 
Number: 28; if: 33344; case: 26495; 
Number: 29; if: 33787; case: 27166; 
Number: 30; if: 33133; case: 26348; 
Number: 31; if: 33285; case: 26431; 
Number: 32; if: 34007; case: 26244; 
Number: 33; if: 32537; case: 25790; 
Number: 34; if: 34048; case: 27169; 
Number: 35; if: 34659; case: 27186; 
Number: 36; if: 34496; case: 26677; 
Number: 37; if: 34159; case: 26197; 
Number: 38; if: 34361; case: 26835; 
Number: 39; if: 34949; case: 26227; 
Number: 40; if: 34886; case: 27272; 
Number: 41; if: 35556; case: 26942; 
Number: 42; if: 34803; case: 26778; 
Number: 43; if: 35009; case: 26524; 
Number: 44; if: 35071; case: 25744; 
Number: 45; if: 35387; case: 26404; 
Number: 46; if: 35842; case: 27084; 
Number: 47; if: 35195; case: 26448; 
Number: 48; if: 36233; case: 26799; 
Number: 49; if: 35613; case: 26100; 
Number: 50; if: 36303; case: 26822; 
Number: 51; if: 35928; case: 26774; 
Number: 52; if: 36706; case: 27083; 
Number: 53; if: 36935; case: 27179; 
Number: 54; if: 37230; case: 26991; 
Number: 55; if: 36007; case: 25683; 
Number: 56; if: 36930; case: 27034; 
Number: 57; if: 36650; case: 26674; 
Number: 58; if: 67032; case: 25945; 
Number: 59; if: 37737; case: 27212; 
Number: 60; if: 38216; case: 27033; 
Number: 61; if: 37665; case: 26877; 
Number: 62; if: 42001; case: 30204; 
Number: 63; if: 38155; case: 26088; 
Number: 64; if: 38277; case: 27103; 
Number: 65; if: 43066; case: 31050; 
Number: 66; if: 38204; case: 26345; 
Number: 67; if: 39259; case: 26782; 
Number: 68; if: 38724; case: 26011; 
Number: 69; if: 38374; case: 26122; 
Number: 70; if: 39079; case: 26555; 
Number: 71; if: 39282; case: 27073; 
Number: 72; if: 39809; case: 27182; 
Number: 73; if: 40076; case: 53457; 
Number: 74; if: 39444; case: 26076; 
Number: 75; if: 39822; case: 26332; 
Number: 76; if: 40346; case: 26030; 
Number: 77; if: 149570; case: 25790; 
Number: 78; if: 40716; case: 26751; 
Number: 79; if: 40952; case: 27367; 
Number: 80; if: 39761; case: 25574; 
Number: 81; if: 40754; case: 26246; 
Number: 82; if: 40939; case: 26086; 
Number: 83; if: 49030; case: 34838; 
Number: 84; if: 41213; case: 27083; 
Number: 85; if: 41758; case: 27152; 
Number: 86; if: 42409; case: 27123; 
Number: 87; if: 43000; case: 53662; 
Number: 88; if: 42675; case: 26538; 
Number: 89; if: 43145; case: 26614; 
Number: 90; if: 44291; case: 27052; 
Number: 91; if: 43460; case: 26231; 
Number: 92; if: 43756; case: 26715; 
Number: 93; if: 43953; case: 26526; 
Number: 94; if: 44467; case: 26277; 
Number: 95; if: 44110; case: 26795; 
Number: 96; if: 44143; case: 27034; 
Number: 97; if: 44582; case: 26810; 
Number: 98; if: 44488; case: 27128; 
Number: 99; if: 43353; case: 25541; 
Average ticks
if:    38416
case:  28164



Но что примечательно — с -O3 становится веселее:
sheridan@amd-gentoo tests % g++ if-case.cpp -O3 -o si; ./si
Number: 0; if: 755; case: 609; 
Number: 1; if: 551; case: 369; 
Number: 2; if: 581; case: 92; 
Number: 3; if: 693; case: 95; 
Number: 4; if: 935; case: 321; 
Number: 5; if: 993; case: 84; 
Number: 6; if: 1075; case: 62; 
Number: 7; if: 1150; case: 51; 
Number: 8; if: 1226; case: 51; 
Number: 9; if: 1426; case: 36; 
Number: 10; if: 1528; case: 39; 
Number: 11; if: 1985; case: 39; 
Number: 12; if: 1831; case: 357; 
Number: 13; if: 2030; case: 39; 
Number: 14; if: 2133; case: 39; 
Number: 15; if: 2337; case: 39; 
Number: 16; if: 2732; case: 39; 
Number: 17; if: 2511; case: 39; 
Number: 18; if: 2730; case: 36; 
Number: 19; if: 2834; case: 39; 
Number: 20; if: 3037; case: 183; 
Number: 21; if: 3137; case: 39; 
Number: 22; if: 3338; case: 36; 
Number: 23; if: 3530; case: 39; 
Number: 24; if: 3512; case: 39; 
Number: 25; if: 3730; case: 36; 
Number: 26; if: 3912; case: 39; 
Number: 27; if: 4135; case: 36; 
Number: 28; if: 4131; case: 39; 
Number: 29; if: 4236; case: 39; 
Number: 30; if: 4410; case: 39; 
Number: 31; if: 4612; case: 39; 
Number: 32; if: 4811; case: 39; 
Number: 33; if: 4812; case: 39; 
Number: 34; if: 5011; case: 39; 
Number: 35; if: 5230; case: 39; 
Number: 36; if: 5354; case: 36; 
Number: 37; if: 5411; case: 39; 
Number: 38; if: 5512; case: 39; 
Number: 39; if: 35450; case: 59; 
Number: 40; if: 33589; case: 84; 
Number: 41; if: 64275; case: 78; 
Number: 42; if: 33887; case: 57; 
Number: 43; if: 33161; case: 33; 
Number: 44; if: 33144; case: 83; 
Number: 45; if: 33733; case: 70; 
Number: 46; if: 34546; case: 46; 
Number: 47; if: 36962; case: 95; 
Number: 48; if: 34618; case: 46; 
Number: 49; if: 34053; case: 52; 
Number: 50; if: 35044; case: 84; 
Number: 51; if: 34377; case: 62; 
Number: 52; if: 35185; case: 57; 
Number: 53; if: 35544; case: 68; 
Number: 54; if: 36047; case: 70; 
Number: 55; if: 34518; case: 73; 
Number: 56; if: 35847; case: 84; 
Number: 57; if: 35945; case: 78; 
Number: 58; if: 35175; case: 70; 
Number: 59; if: 36113; case: 62; 
Number: 60; if: 36823; case: 55; 
Number: 61; if: 36445; case: 46; 
Number: 62; if: 40863; case: 44; 
Number: 63; if: 36349; case: 33; 
Number: 64; if: 37601; case: 46; 
Number: 65; if: 41454; case: 33; 
Number: 66; if: 39935; case: 59; 
Number: 67; if: 37331; case: 33; 
Number: 68; if: 37041; case: 166; 
Number: 69; if: 36971; case: 33; 
Number: 70; if: 38330; case: 33; 
Number: 71; if: 38005; case: 33; 
Number: 72; if: 38024; case: 51; 
Number: 73; if: 38669; case: 64; 
Number: 74; if: 71977; case: 33; 
Number: 75; if: 38371; case: 33; 
Number: 76; if: 38512; case: 171; 
Number: 77; if: 37720; case: 33; 
Number: 78; if: 39114; case: 33; 
Number: 79; if: 39354; case: 33; 
Number: 80; if: 38091; case: 46; 
Number: 81; if: 39491; case: 33; 
Number: 82; if: 38923; case: 33; 
Number: 83; if: 47743; case: 66; 
Number: 84; if: 39830; case: 195; 
Number: 85; if: 40184; case: 33; 
Number: 86; if: 40256; case: 33; 
Number: 87; if: 40155; case: 33; 
Number: 88; if: 39334; case: 33; 
Number: 89; if: 41203; case: 33; 
Number: 90; if: 41140; case: 33; 
Number: 91; if: 43434; case: 33; 
Number: 92; if: 40837; case: 33; 
Number: 93; if: 40885; case: 33; 
Number: 94; if: 41071; case: 33; 
Number: 95; if: 41320; case: 62; 
Number: 96; if: 43622; case: 26; 
Number: 97; if: 41465; case: 46; 
Number: 98; if: 42022; case: 33; 
Number: 99; if: 43249; case: 293; 
Average ticks
if:    25858
case:  945
Matrix has you...
Re[3]: Померять я завсегда готов :)
От: Sheridan Россия  
Дата: 10.02.12 16:30
Оценка:
Здравствуйте, watch-maker, Вы писали:

WM>Тест плохой.

http://www.rsdn.ru/forum/cpp/4612690.1.aspx
Автор: Sheridan
Дата: 10.02.12
Matrix has you...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.