1. C++ / Говнокод #11661

    +42

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    std::string loc =
    	( {
    		const char *str = "";
    
    		switch (location) {
    		case Net::HANDSHAKE_TIMEOUT:
    			str = _(" due to handshake timeout");
    			break;
    		case Net::RECV_HANDSHAKE:
    			str = _(" while waiting for handshake");
    			break;
    		case Net::HANDSHAKE_DATA:
    			str = _(" due to unsupported handshake data");
    			break;
    		case Net::HANDSHAKE_AUTH:
    			str = _(" while parsing handshake data");
    			break;
    		case Net::WAIT_DEVICE:
    			str = _(" while waiting for device");
    			break;
    		case Net::TRANSFER_DATA:
    			str = _(" while transferring data");
    			break;
    		}
    		str;
    	});

    Я хуею с юных оптимизаторов.

    Запостил: gvy, 28 Августа 2012

    Комментарии (23) RSS

    • GCC'изм, разрешающий {} внутри выражений?

      http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
      Ответить
    • Инициализация переменной case-выражением? Да, есть такое в Аде, а что?
      Ответить
    • const char *str = "";
      
      		switch (location) {
      		case Net::HANDSHAKE_TIMEOUT:
      			str = _(" due to handshake timeout");
      			break;
      		case Net::RECV_HANDSHAKE:
      			str = _(" while waiting for handshake");
      			break;
      		case Net::HANDSHAKE_DATA:
      			str = _(" due to unsupported handshake data");
      			break;
      		case Net::HANDSHAKE_AUTH:
      			str = _(" while parsing handshake data");
      			break;
      		case Net::WAIT_DEVICE:
      			str = _(" while waiting for device");
      			break;
      		case Net::TRANSFER_DATA:
      			str = _(" while transferring data");
      			break;
      		}
      std::string loc = str;
      Ответить
    • можно еще присваивание с бряком на ретурн заменить. И убрать str переменную.
      Ответить
    • Не вижу в этом коде никакого оптимизаторства. Нафига использовали нестандартное расширение без особой нужды - это можно спросить. А оптимизаторства тут никакого нет.
      Ответить
      • Ну я имел ввиду, что какого так писать. Это надо быть ебанутым на всю голову, чтобы switch туда впихнуть. Вот переписанный код, к которому нет никаких претензий.

        const char* get_error(Net::EErrorLocation location)
        {
        const char *str = "";

        switch (location) {
        case Net::HANDSHAKE_TIMEOUT:
        str = _(" due to handshake timeout");
        break;
        case Net::RECV_HANDSHAKE:
        str = _(" while waiting for handshake");
        break;
        case Net::HANDSHAKE_DATA:
        str = _(" due to unsupported handshake data");
        break;
        case Net::HANDSHAKE_AUTH:
        str = _(" while parsing handshake data");
        break;
        case Net::WAIT_DEVICE:
        str = _(" while waiting for device");
        break;
        case Net::TRANSFER_DATA:
        str = _(" while transferring data");
        break;
        }

        return str;
        }

        std::string loc = get_error(location);
        Ответить
        • Мапу используй.
          Ответить
        • > Вот переписанный код, к которому нет никаких претензий.
          А я бы все-таки вот так переписал (если мапа/массив не подходит):
          const char* get_error(Net::EErrorLocation location)
          {
              switch (location) {
              case Net::HANDSHAKE_TIMEOUT:
                  return _(" due to handshake timeout");
              case Net::RECV_HANDSHAKE:
                  return _(" while waiting for handshake");
              case Net::HANDSHAKE_DATA:
                  return _(" due to unsupported handshake data");
              case Net::HANDSHAKE_AUTH:
                  return _(" while parsing handshake data");
              case Net::WAIT_DEVICE:
                  return _(" while waiting for device");
              case Net::TRANSFER_DATA:
                  return _(" while transferring data");
              }
              return "";
          }
          Ответить
          • Кстати, а вот кто как выбирает правильный алгоритм поиска?
            1) Линейный поиск. Например в std::vector. O(n)
            2) std::map. O(log n)
            3) std::unordered_map. O(1)
            4) boost::flat_map/Loki::AssocVector. O(log n)
            5) Таблица. О(1)
            6) ...
            ?
            От каких критериев отталкиваетесь при выборе?
            Ответить
            • А не выберешь только по поиску требуемую структуру данных. Нужно учитывать частоту и характер остальных операций над структурой.

              > От каких критериев отталкиваетесь при выборе?
              Составляешь список основных операций, которые будут выполняться, пытаешься оценить насколько часто они будут использоваться. На основе этих рассуждений можно выбрать наиболее удобную структуру.

              Если есть возможность, имхо, стоит инкапсулировать выбранную структуру данных внутри какого-нибудь более-менее высокоуровневого модуля\класса (игровое поле, фабрика объектов и т.п.), дабы если потом возникнет желание заменить ее на другую, не пришлось перелопачивать код в зависимых модулях\классах.
              Ответить
          • "А я бы все-таки вот так переписал (если мапа/массив не подходит)" - я думаю, компилятор в обеих случаях сгенерирует одинаковый код.

            Массив не подходит, коды не идут подряд. map тем более не нужен для такого маленького числа вариантов, он будет работать медленнее, чем этот switch.
            Ответить
            • > я думаю, компилятор в обеих случаях сгенерирует одинаковый код.
              Я не из-за производительности переписал бы, она тут всяко будет одинаковая, да и не сильно она важна в обработчиках ошибок.

              Я переписал бы чисто из-за удобства - с return выходит меньше кода, меньше возможности накосячить, легче читать.

              >Массив не подходит, коды не идут подряд. map тем более не нужен для такого маленького числа вариантов, он будет работать медленнее, чем этот switch.
              Ну собственно поэтому и написал "если мапа/массив не подходит".
              Ответить
              • > производительность тут всяко будет одинаковая, да и не сильно она важна в обработчиках ошибок.
                Я видел проекты, где система тормозила именно из-за обработчиков ошибок, а именно из-за постоянного падения исключений "до низа стека".
                Ответить
                • > Я видел проекты, где система тормозила именно из-за обработчиков ошибок
                  Тоже с подобным проектом встречался... несложный скриптовый двиг, но автор не знал про TryStrToFloat, и юзал вместо него StrToFloat. Причем вызывалась эта гадость на каждый чих - на каждом операторе '+', чтобы выяснить типы аргументов. Вот там замена try { StrToFloat() } на TryStrToFloat() подняла производительность на порядок ;)

                  Но в нормальных ситуациях, когда все идет по плану, исключение это все-таки исключительная ситуация. Поэтому их оптимизация почти всегда преждевременная.
                  Ответить
                  • boost::optional
                    or
                    Data.Maybe
                    or
                    type?
                    or
                    Nullable
                    Но таки TryStrToFloat это не осилил
                    Ответить
                    • Не понял вашу мысль.
                      Ответить
                      • Ну псевдокод на псевдохаскеле
                        TryStrToFloat str =
                        ...
                        If (удалось сконвертировать строку str в a::Float)
                          Just a
                        else
                          Nothing
                        Ответить
                        • А создатели шарпофреймворка что-то типа
                          float?
                          или
                          Nullable<float>
                          вернуть из TryStrToFloat не осилили.
                          Ответить
                          • Это был TryStrToFloat из с++ builder. Суть такая:
                            float f;
                            if (TryStrToFloat(s, f)) {
                                // удалось, делаем чего-нибудь с f
                            } else {
                                // не удалось
                            }
                            Ответить
                            • Пф. Тоже самое, только у C# TryParse например. Вертать данные через правую часть функции - муветон по надежности. Позволяет воспользоваться не верно инициализированным f в случае неудачи парсинга.
                              Ответить

    Добавить комментарий