Форум программистов, компьютерный форум, киберфорум
Наши страницы
CoderHuligan
Войти
Регистрация
Восстановить пароль
Рейтинг: 2.33. Голосов: 6.

goto и switch

Запись от CoderHuligan размещена 24.06.2019 в 10:22
Обновил(-а) CoderHuligan 24.06.2019 в 13:08

Вижу, что многие не понимают сути "народного" подхода, поступают вопросы, на которые следует ответить.
Цитата:
Сообщение от voral
Более того применение флагов не имеет отношение к выбору с GOTO или без оного. Это вещи разного порядка. (Мне все больше кажется, что вы не совсем верно толкуете "структурное" программирование). Флаги это не состояние программы в целом, или на какой то момент времени... Это лишь характеристика конкретной сущности. Которая может меняться, а может не меняться.
Вы несколько ошибаетесь. Флаги не описывают свойства обьекта управления. Флаг это чисто логическая переменная, которая может содержать лишь два значения - false и true. В структурном программировании, так как goto запрещен, флаги используются для изменения потока управления. По сути это костыль, который неуклюжим образом заменяет прямой переход. Если с goto я могу перейти в единственное состояние, то с флагами я вынужден дробить это состояние на множество блоков кода и множество идентичных флагов, при помощи которых, эти блоки кода "включаются" и "выключаются". Прямо скажем: ужасный подход, что отмечали многие. Доцент кафедры программирования ИТМО Шалыто говорит, что это просто преступный подход, так программировать нельзя. Он предлагает свитч-технологию для избавления от этих флагов. Например взять прежний пример подсчёта слов на goto:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#define N 255
char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
int main(void)
{
 
    int nw = 0;
    
    char *p=s;
        --p;
    OUT:
        ++p;
        if(!*p)
            goto K;
        if(*p == ' ' || *p == ',' || *p == '\n')
            goto OUT;
        nw++; 
            goto IN;
    IN:
        if(!*p)
            goto K;
        if(*p == ' ' || *p == ',' || *p == '\n')
            goto OUT;
        ++p; 
            goto IN;
    K:
    printf ("%d \n",  nw);
    return 0;
}
и преобразуем его в соответствии с свитч-технологией:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#define N 255
#define IN 1
#define OUT 2
#define K 3
#define END 4
char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
int main(void)
{
 
    int nw = 0, state;
    
    char *p=s;
    state = OUT;
        --p;
    while(state!=END)
    {
        switch(state)
        {
            case OUT:
                ++p;
                if(!*p)
                    {state = K; break;}
                if(*p == ' ' || *p == ',' || *p == '\n')
                    {state = OUT; break;}
                nw++; 
                    {state = IN; break;}
            break;
            case IN:
                if(!*p)
                    {state = K; break;}
                if(*p == ' ' || *p == ',' || *p == '\n')
                    {state = OUT; break;}
                ++p; 
                   {state = IN; break;}
                    break;
            case K:
            printf ("%d \n",  nw);
            state = END; break;
 
        }
    }
    return 0;
}
Как видим логика осталась практически той же. Переходы обеспечиваются попаданием через цикл в соответствующие ветки case. Умный компилятор преобразует их в таблицу указателей на метки и на выходе получим те же самые goto. Эта технология гораздо лучше структурного подхода, так как позволяет избавится от флагов, и позволяет реализовать даже самый супер-пупер сложный алгоритм. Это будущее робототехники и ИИ.
В моём случае я действую по старинке, не пряча оператор goto. Мой код может обработать любой компилятор, даже самый "тупой".

Цитата:
Сообщение от voral
Сути не меняет, я тоже именно про условную конструкцию, она всегда имеет, по сути одну точку выхода, эта точка следует срезу после конструкции... "Внутри" возможны лишь искусственные выходы, а это уже дело рук программиста. И вот тут и проявляется правильность подхода. В общем случае программ не должна улетать куда либо (как раз в вашем случае она делает это всегда). И лишь четко в обоснованных случаях это обоснованно
Если эта конструкция имеет не одну точку выхода, то она уже не имеет права называться структурной. Это первое.
Во-вторых, моя программа никуда "не улетает". Она просто делает то, что предписано алгоритмом решения задачи. Если алгоритм предписывает куда-то перейти, например в начало, то код обеспечивает эту возможность. Вы же видите, даже такой простой код, уже настолько умён, что позволяет прерывать программу на любом шаге, входить в режим помощи на любом шаге и рестартовать программу. Даже если мы находимся на полпути расстановки кораблей на поле, можно сразу всё начать заново, сбросив все настройки. Из режима помощи можно вернутся в туже точку расстановки кораблей и продолжить с того же самого места. Напишите это в традиционном стиле.
Размещено в Без категории
Просмотров 861 Комментарии 46
Всего комментариев 46
Комментарии
  1. Старый комментарий
    Вся проблема в том, что код, который вы написали для демонстрации структурного подхода написан черте как... И если вы такой код увидите в реальном проекте, можете отправлять автора смело в школу. Я еле понял чего вы хотите в этом коде сделать, могли бы уж алгоритм как то еще больше усложнить
    Запись от voral размещена 24.06.2019 в 11:02 voral вне форума
  2. Старый комментарий
    я бы написал так (хотя я тоже не претендую на звания аса программирования на сях, переход в нишу веб программирования накладывает свой отпечаток )

    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    #include <stdio.h>
    #define N 255
    char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
    int main(void)
    {
        int nw = 0;
        char *p=s;
        int prev = 0;
        while (*p) {
            if( *p == ' ' || *p == ',' || *p == '\n') {
                if (prev == 1) ++nw;
                prev = 0;
            } else {
                prev = 1;
            }
            ++p;
        }
        nw += prev;
        printf ("%d \n",  nw);
        return 0;
    }
    Запись от voral размещена 24.06.2019 в 11:11 voral вне форума
  3. Старый комментарий
    Цитата:
    Умный компилятор преобразует их в таблицу указателей на метки и на выходе получим те же самые goto. Эта технология гораздо лучше структурного подхода, так как позволяет избавится от флагов, и позволяет реализовать даже самый супер-пупер сложный алгоритм. Это будущее робототехники и ИИ.
    В моём случае я действую по старинке, не пряча оператор goto. Мой код может обработать любой компилятор, даже самый "тупой".
    А при чем тут компилятор? Мы с вами о читабельности кода, а не о том во что превращает его компилятор.
    На "супер-пупер сложный алгоритм" это будет треш и ужас с вашими GOTO... Потому что возможность ошибки возрастает многократно... Стоит опечататься (вместо L111 поставить L11) или метку на строчку раньше вбабахат ("благо" отсутпов у вас практически не будет).... И все.... В строчку 17 вашего листинга "структурного варианта" можно попасть только одним путем. В строчку 12 вашего листинга вашего метода можно попасть из любой точки программы. Привет бессоные ночи...

    А если говорить о разработке в команде, чужого кода, или свой код через год....... Это жесть.. Годится только с точки зрения академической. не более.
    Запись от voral размещена 24.06.2019 в 11:27 voral вне форума
  4. Старый комментарий
    Цитата:
    Мой код может обработать любой компилятор, даже самый "тупой".
    А в чем проблема для компилятора обработать код структурного программирования? Т.е. так программирует большинство и все испытывают проблемы с компиляцией? Или вы о том что компилировать современный код, компилятором года этак 1980го?
    Запись от voral размещена 24.06.2019 в 11:30 voral вне форума
  5. Старый комментарий
    Использование Goto может привести к ошибкам.
    На анимационной картинке показаны 2 кода, отличающиеся тем что в первом выход по Break, а во втором используя Goto. Первый работает нормально, а во втором ошибка при выходе из функции. Догадайтесь почему.
    Кликните здесь для просмотра всего текста
    Запись от locm размещена 24.06.2019 в 12:45 locm вне форума
  6. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от locm Просмотреть комментарий
    Догадайтесь почему.
    Потому что в качестве имени метки используется предопределённое имя. Точно также как с любыми переменными, именами функций и т.д.
    Запись от CoderHuligan размещена 24.06.2019 в 13:18 CoderHuligan вне форума
  7. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от voral Просмотреть комментарий
    Вся проблема в том, что код, который вы написали для демонстрации структурного подхода
    Не для демонстрации структурного, а для демонстрации НЕструктурного.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    я бы написал так
    Так я от подобного алгоритма изначально отталкивался: http://www.cyberforum.ru/blogs/622334/blog5834.html
    Мой код эффективнее вашего на 30-50%. Мы в том же уроке в комментах это сравнивали. Правда некоторые опять пытались выдать желаемое за действительное, но оставим это на их совести.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    А при чем тут компилятор? Мы с вами о читабельности кода, а не о том во что превращает его компилятор.
    Неоптимизирующий компилятор не сможет преобразовать свитч в таблицу переходов.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    Стоит опечататься (вместо L111 поставить L11) или метку на строчку раньше вбабахат ("благо" отсутпов у вас практически не будет).... И все....
    Это можно выявить на стадии тестирования. Вообще же здесь goto вообще не причём. Я вам покажу сотни примеров как опечатываются в обычном коде при полном молчании компилятора.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    В строчку 12 вашего листинга вашего метода можно попасть из любой точки программы. Привет бессоные ночи...
    А если программа разбита на модули? Или на функции. Каждая метка в своём модуле или функции уникальна, даже если имеет одно и то же имя.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    А если говорить о разработке в команде, чужого кода, или свой код через год....... Это жесть.. Годится только с точки зрения академической. не более.
    Соблюдая некоторые элементарные соглашения по написанию кода можно избежать проблем, тем более, что большинство из них надуманные.
    Запись от CoderHuligan размещена 24.06.2019 в 13:27 CoderHuligan вне форума
  8. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Не для демонстрации структурного, а для демонстрации НЕструктурного.
    Да обзовите как хотите. Второй листинг это треш.


    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Мой код эффективнее вашего на 30-50%. Мы в том же уроке в комментах это сравнивали.
    Как раз таки тесты показывают, что ваш код не дает ни какого профита. Да вы можете выключить оптимизацию и наслаждаться... Но на практике это ни кому не нужно. Приведу вам пример: в свое время помогал написать программу для научных расчетов температуры головки молнии. Изанчально была написали на Turbo Pascal 5.5 при запуске на 386 компе расчет длился порядка суток. Потом я исключительно саму математику переписал на asm. При тех же самых исходных данных расчет стал выполнятся 4 часа. Профит!!! Казалось бы сейчас половина кода тогда должна быть на асме и не на чем больше. Но!.... Провел я году в 2005 похожий эксперимент с бенчмарками... Фиг вам. Современные компиляторы стали значительно умнее. Так же и в этом случае.
    Т.е. если уж проводить сравнения, то именно в тех условиях как это будет на продакшене. Ну если только вас интересует это не только с академической точки зрения.

    В замен мы получаем сложно поддерживаемый код.


    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Неоптимизирующий компилятор не сможет преобразовать свитч в таблицу переходов.
    А давайте вообще ориентироваться на 16ти битную архитектуру всегда... Ну так, вдруг у когото супер сервер на ней построен...

    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Это можно выявить на стадии тестирования. Вообще же здесь goto вообще не причём. Я вам покажу сотни примеров как опечатываются в обычном коде при полном молчании компилятора.
    Дело не в наличии примеров. Я вам сам могу целую книгу по этому написать, т.к. много работаю с чужим кодом. В вашем коде сделать это (допустить тихую ошибку) в разы проще.

    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Соблюдая некоторые элементарные соглашения по написанию кода можно избежать проблем, тем более, что большинство из них надуманные.
    Понимаете в чем дело, если бы все упиралось в соглашения, то ошибок в программах было бы значительно меньше. Но человек не робот (опять же с идеальной прошивкой).. По этому тут надо подходить по принципу "На бога надейся, но сам не оплошай".. И в случае без гото, сам код "защищает" себя от множества ошибок присущих стилю с ГОТО... При этом можете показать ошибки на которые не ругнется компилятор, и которые не возможны в вашем подходе?
    Запись от voral размещена 24.06.2019 в 13:52 voral вне форума
  9. Старый комментарий
    Аватар для XLAT
    мой вариант:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    #include <stdio.h>
    #define N 255
    char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
     
    int main()
    {
        int  nw = 0;
        char *p = s;
        
        while (*p)
        {   while ( *p == ' ' || *p == ',' || *p == '\n') p++;
            if(*p++ == 0) break;
            nw++;
            while ( *p != ' ' && *p != ',' && *p != '\n' && *p) p++;
        };
     
     
        printf ("%d \n",  nw);
        return 0;
    }
    CoderHuligan, как будем мерить эффективность то???
    Запись от XLAT размещена 24.06.2019 в 13:58 XLAT вне форума
    Обновил(-а) XLAT 24.06.2019 в 14:11
  10. Старый комментарий
    На самом деле, никакие подобные издевательства над кодом в наше время не имеют смысла, поскольку во первых в 99% задач рост производительности на считанные проценты не приносит никакого профита, а вот усложнение написания и сопровождения кода приводит к вполне ощутимым потерям. Еще 0.99% задач, где производительность имеет значение, современные оптимизирующие компиляторы прекрасно с этой задачей справляются и опять же городить готу нет абсолютно никакого смысла, компилятор сам нагородит где нужно. Не исключено, что нагородит даже лучше, чем вы. И лишь в оставшемся мизерном 0.01% иногда приходится что-то оптимизировать вручную, или даже писать ассемблерные вставки.
    Запись от Катафалк размещена 24.06.2019 в 15:00 Катафалк вне форума
  11. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от voral Просмотреть комментарий
    В замен мы получаем сложно поддерживаемый код.
    Вы так считаете, потому-что видите лишь часть проблемы. Код, сырой код, это ещё не весь документ, в том подходе, который я исповедую. А у вас сырой код это весь документ. А я знаю, как сложно догадываться что тут в данном месте имел в виду программист, которому лень оставить вменяемый комментарий в "самодокументируемом" коде..
    Цитата:
    Сообщение от XLAT Просмотреть комментарий
    как будем мерить эффективность то???
    Просто. Сегодня уже не смогу сравнить. Позже выложу результаты.
    Цитата:
    Сообщение от Катафалк Просмотреть комментарий
    опять же городить готу нет абсолютно никакого смысла, компилятор сам нагородит где нужно. Не исключено, что нагородит даже лучше, чем вы.
    GOTO нужен для упрощения и реализации алгоритма. Это средство АЛГОРИТМИЗАЦИИ.
    Запись от CoderHuligan размещена 24.06.2019 в 16:30 CoderHuligan вне форума
  12. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Код, сырой код, это ещё не весь документ, в том подходе, который я исповедую. А у вас сырой код это весь документ.
    После этой фразы, я совсем не понимаю, что в Вашем понимании документ.
    Запись от voral размещена 24.06.2019 в 16:33 voral вне форума
  13. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    А я знаю, как сложно догадываться что тут в данном месте имел в виду программист, которому лень оставить вменяемый комментарий в "самодокументируемом" коде..
    Вы совершенно не верно, похоже, трактуете термин "самодокументируемый".

    Самодокументируемый код это не одно и то же что код с комментариями. Одно другое не исключает, а дополняет. Как раз коментарии нужны исключительно там, где могут быть разночтения кода. Поскольку код построенный на GOTO имеет меньшую степень самодокументируемости, просто "по определению", то в таком коде комментариев просто обязательно должно быть больше.
    Запись от voral размещена 24.06.2019 в 16:37 voral вне форума
  14. Старый комментарий
    Аватар для XLAT
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Просто. Сегодня уже не смогу сравнить. Позже выложу результаты.
    ок, вот сляпал на скорую руку
    Это первый вариант:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    
    ///----------------------------------------------------------------------------|
    /// Стенд для замера пииисек: мой против хулигана.
    ///     1 число - счетчик слов;
    ///     2 число - кол-во тактов на один проход;
    ///     3 число - текущая сумма тактов всех проходов.
    ///----------------------------------------------------------------------------:
    #include <stdio.h>
    #include <cmath>
     
    ///----------------------------------------------------------------------------|
    /// Мерилка тактов проца.
    ///----------------------------------------------------------------------------:
    typedef unsigned long long ull;
    inline ull rdtsc()
    {   unsigned int lo, hi;
        asm volatile ( "rdtsc\n" : "=a" (lo), "=d" (hi) );
        return ((ull)hi << 32) | lo;
    }
     
    ///----------------------------------------------------------------------------|
    /// Для удобства.
    ///----------------------------------------------------------------------------:
    #define START_PERFOMANCE  ull t1 = rdtsc(); static ull ss_  = 0
    #define END_PERFOMANCE(v) ull v  = rdtsc(); v -= t1;   ss_ += v
     
    ///----------------------------------------------------------------------------|
    /// Хулиган.
    ///----------------------------------------------------------------------------:
    ull CoderHuligan(char* s)
    {   int nw = 0;
        char *p=s;
        
    START_PERFOMANCE;
            --p;
        OUT1:
            ++p;
            if(!*p)
                goto K;
            if(*p == ' ' || *p == ',' || *p == '\n')
                goto OUT1;
            nw++; 
                goto IN1;
        IN1:
            if(!*p)
                goto K;
            if(*p == ' ' || *p == ',' || *p == '\n')
                goto OUT1;
            ++p; 
                goto IN1;
        K: 
    END_PERFOMANCE(t2);
     
        printf ("CoderHuligan: %d %+6u ", nw, t2);
        printf ("%+10u \n\n",  ss_);
        
        return ss_;
    }
     
    ///----------------------------------------------------------------------------|
    /// my.
    ///----------------------------------------------------------------------------:
    ull my(char* s)
    {   int  nw = 0;
        char *p = s;
        
    START_PERFOMANCE;
        while (*p)
        {   while ( *p == ' ' || *p == ',' || *p == '\n') p++;
            if(*p++ == 0) break;
            nw++;
            while ( *p != ' ' && *p != ',' && *p != '\n' && *p) p++;
        };
    END_PERFOMANCE(t2);
        
        printf ("my:           %d %+6u ",  nw, t2);
        printf ("%+10u \n",  ss_);
        
        return ss_;
    }
     
    ///----------------------------------------------------------------------------|
    /// Наш кролик.
    ///----------------------------------------------------------------------------:
    char s[]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
     
    ///----------------------------------------------------------------------------|
    /// Start.
    ///----------------------------------------------------------------------------:
    int main()
    {   
        ull m,c;
        for(int i = 0; i < 100; ++i)
        {   m = my          (s);
            c = CoderHuligan(s);
        }
        
        double ef = 100.0/double(c) * double(m) - 100.0;
        printf ("Profitable CoderHuligan: %2.2f%%\n\n",  ef);
        
        return 0;
    }
    чуть позже может быть(если не забуду) сделаю второй,
    идея второго варианта будет такова: берем минимальное значение выборки из общей серии от каждой пиииски и выводим в результат.

    По результатам на моем компе(TDM-GCC 4.9.2):
    ваши гоутушки на 2% круче быстрее.
    Запись от XLAT размещена 24.06.2019 в 16:45 XLAT вне форума
    Обновил(-а) XLAT 24.06.2019 в 17:54
  15. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Потому что в качестве имени метки используется предопределённое имя. Точно также как с любыми переменными, именами функций и т.д.
    Ошибка происходит на этапе выполнения, а не при компиляции. Ясно же написано что происходит обращение к памяти по нулевому адресу.
    Запись от locm размещена 24.06.2019 в 17:46 locm вне форума
  16. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от locm Просмотреть комментарий
    Ошибка происходит на этапе выполнения, а не при компиляции. Ясно же написано что происходит обращение к памяти по нулевому адресу.
    Значит криво сляпан компилятор бейсика. Не гото же виноват))
    На си всё в порядке, полёт нормальный. Иногда требуется, правда поставить оператор завершения ;(точку с запятой). В бейсике его нет, так что даже не знаю как там это исправить.
    Запись от CoderHuligan размещена 24.06.2019 в 18:53 CoderHuligan вне форума
    Обновил(-а) CoderHuligan 24.06.2019 в 18:58
  17. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от voral Просмотреть комментарий
    После этой фразы, я совсем не понимаю, что в Вашем понимании документ.
    Позже объясню.
    Запись от CoderHuligan размещена 24.06.2019 в 18:54 CoderHuligan вне форума
  18. Старый комментарий
    Аватар для XLAT
    CoderHuligan,
    новости для вас неутешительные, увы...

    тест по второму варианту, по моему мнению более совершенному,
    ваши гоутушки провалили:

    вот сам тест:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    
    /// TDM-GCC 4.9.2
    ///----------------------------------------------------------------------------|
    /// Стенд для замера пииисек: мой против хулигана.
    ///     1 число - счетчик слов;
    ///     2 число - кол-во тактов на один проход;
    ///     Каждая новая строка есть прогресс по меньшему кол-ву тактов!
    ///
    ///     my - самый выдающийся финиш с 442 тактами! (100'000'000 проходов)
    ///     ...
    ///     10 минут спустя:
    ///     на миллиарде проходов(1'000'000'000)
    ///     CoderHuligan: 462 - looser...
    ///     my:           441 - WIN <<<---!!!
    ///     ...
    ///     CoderHuligan, не плачьте!
    ///----------------------------------------------------------------------------:
    #include <stdio.h>
    //#include <conio.h>
     
    ///----------------------------------------------------------------------------|
    /// Мерилка тактов проца.
    ///----------------------------------------------------------------------------:
    typedef unsigned long long ull;
    inline ull rdtsc()
    {   unsigned int lo, hi;
        asm volatile ( "rdtsc\n" : "=a" (lo), "=d" (hi) );
        return ((ull)hi << 32) | lo;
    }
     
    ///----------------------------------------------------------------------------|
    /// Для удобства.
    ///----------------------------------------------------------------------------:
    #define START_PERFOMANCE  ull t1 = rdtsc(); static ull ss_  = 0xffffffff;\
        bool b = false
    #define END_PERFOMANCE ull v  = rdtsc(); v -= t1;\
        if(ss_ > v){ b = true; ss_ = v;}
     
    ///----------------------------------------------------------------------------|
    /// Хулиган.
    ///----------------------------------------------------------------------------:
    ull CoderHuligan(char* s)
    {   int nw = 0;
        char *p=s;
     
    START_PERFOMANCE;
            --p;
        OUT:
            ++p;
            if(!*p)
                goto K;
            if(*p == ' ' || *p == ',' || *p == '\n')
                goto OUT;
            nw++;
                goto IN;
        IN:
            if(!*p)
                goto K;
            if(*p == ' ' || *p == ',' || *p == '\n')
                goto OUT;
            ++p;
                goto IN;
        K:
    END_PERFOMANCE;
     
        if(b)
        {   printf ("CoderHuligan: %d ", nw);
            printf ("%10u \n",  (unsigned)ss_);
            b = false;
        }
     
        return ss_;
    }
     
    ///----------------------------------------------------------------------------|
    /// my.
    ///----------------------------------------------------------------------------:
    ull my(char* s)
    {   int  nw = 0;
        char *p = s;
     
    START_PERFOMANCE;
        while (*p)
        {   while ( *p == ' ' || *p == ',' || *p == '\n') p++;
            if(*p++ == 0) break;
            nw++;
            while ( *p != ' ' && *p != ',' && *p != '\n' && *p) p++;
        };
    END_PERFOMANCE;
     
        if(b)
        {   printf ("my:           %d ",  nw);
            printf ("%10u \n",  (unsigned)ss_);
            b = false;
        }
     
        return ss_;
    }
     
    ///----------------------------------------------------------------------------|
    /// Наш кролик.
    ///----------------------------------------------------------------------------:
    char s[]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
     
    ///----------------------------------------------------------------------------|
    /// Start.
    ///----------------------------------------------------------------------------:
    int main()
    {
        ull m,c;
     
        //-------------------------------|
        // Quiet, testing!               |
        //-------------------------------:
        for(int i = 0; i < 10000000; ++i)
        {   c = CoderHuligan(s);
            m = my          (s);
        }
     
        //-------------------------------|
        // Banners is redy...            |
        //-------------------------------:
        const char* str[2] = {"WIN <<<--!!!", "looser..."};
        int i1, i2;
        (m > c) ? (i1 = 0, i2 = 1) : (i1 = 1, i2 = 0);
     
        //-------------------------------|
        // Finish result.                |
        //-------------------------------:
        printf ("\nFinish the race-------------------:\n");
        printf ("CoderHuligan: %u - ", (unsigned)c);
        printf ("%s\n", str[i1]);
        printf ("my:           %u - ", (unsigned)m);
        printf ("%s\n", str[i2]);
     
        //-------------------------------|
        // Show efficiency.              |
        //-------------------------------:
        double ef = 100.0/double(c) * double(m) - 100.0;
        printf ("\nProfitable CoderHuligan: %2.2f%%\n\n",  ef);
     
        //_getch();
        return 0;
    }
    https://ideone.com/ua8I2E
    http://cpp.sh/3zxzd
    https://rextester.com/ZVJG42008
    Запись от XLAT размещена 24.06.2019 в 20:15 XLAT вне форума
    Обновил(-а) XLAT 24.06.2019 в 23:09
  19. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от XLAT Просмотреть комментарий
    CoderHuligan,
    новости для вас неутешительные, увы...

    тест по второму варианту, по моему мнению более совершенному,
    ваши гоутушки провалили:
    Проверил ваш код и код voral. Код voral всегда на 30% медленнее. Вы прекрасно справились с задачей! Поздравляю! И подтверждаю ваши результаты - сейчас сам провёл эксперимент. В коде вы разделили оба состояния, что и привело к подобному результату. Разница в 1-2% несущественна, так как код с goto современные компиляторы не оптимизируют. Например вставляют пустые операции после каждого goto, что несколько замедляет программу.
    Вы смогли это сделать потому, что код примера очень прост.
    Запись от CoderHuligan размещена 25.06.2019 в 10:40 CoderHuligan вне форума
  20. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Значит криво сляпан компилятор бейсика. Не гото же виноват))
    Дело не в компиляторе, а в использовании Goto.
    Состояние стека в момент ошибки. Найдите отличия.
    Кликните здесь для просмотра всего текста
    Запись от locm размещена 25.06.2019 в 11:34 locm вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru