Оптимизация операторов "else if"

Тема в разделе "WASM.A&O", создана пользователем gringoz0id, 19 янв 2012.

  1. gringoz0id

    gringoz0id New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2011
    Сообщения:
    6
    Друзиа, "обращаюсь не корысти ради, а токмо воли пославшей мя жоны" (с)
    В наследство достался блок кода, состоящий из пары сотен операторов "switch" и "else if"
    Что-то типа такого:
    Код (Text):
    1. void detectError(int* errCode)
    2. {
    3.          char * error;
    4.     *errCode = WSAGetLastError();
    5.  
    6.     if ( *errCode == WSANOTINITIALISED )
    7.         // error = '"";
    8.     else if ( *errCode == WSAENETDOWN )
    9.         // error = '"";
    10.     else if ( *errCode == WSAEAFNOSUPPORT )
    11.         // error = '"";
    12. ..........
    13.         много else if
    Как можно избавиться от этого ужоснаха, оптимизировать код, увеличить скорость исполнения штатными средствами, без использования сторонних либ типа Boost'a?
    Буду очень признателен любым дельным предложениям и пинкам в нужную сторону.
     
  2. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    gringoz0id
    Если оптимизировать по скорости, то этот код лучше вообще не трогать. Или ошибок так много, что их обработка самое узкое место программы?!
     
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    gringoz0id
    1) здесь рассматривался сходный вопрос
    2) а что за либа Boost'a?
     
  4. gringoz0id

    gringoz0id New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2011
    Сообщения:
    6
    Black_mirror
    Ошибок немного на самом деле. Эта функция является частью системы логирования и автор, видимо, хотел предусмотреть все возможные варианты.
    Mikl___
    Это Boost :) За ссылку спасибо, изучаю
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    gringoz0id
    Ну и зачем ее тогда оптимизировать, если и ошибки возникают редко и само логирование наверняка пожирает намного больше времени, чем все эти ифы? Если эта функция должна обрабатывать не только ошибки, но и штатные отказы типа WSAEWOULDBLOCK и т.п., то их можно проверять в первую очередь с выходом по return
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Юзать мапу, ключ - код ошибки, значение - указатель на функцию обработчик, лучше лямбду.
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Booster
    Я примерно, то же самое подсказал, а вот
    это, наверное, ссылка на какую-то вашу библиотеку?
     
  8. gringoz0id

    gringoz0id New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2011
    Сообщения:
    6
    Booster
    Спасибо за подсказку
    Mikl___
    www.boost.org
     
  9. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Самый быстрый - завернуть каждую ветку ELSEIF в функцию, сделать таблицу указателей на функции, где errCode - порядковый номер элемента в таблице, потом читать указатель из таблицы и вызывать по нему функцию. Если эти коды сильно разреженные, хреначим таблицу соответствий "код ошибки - указатель на функцию", сортируем и ищем в ней бинарным поиском.
     
  10. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    А разве switch/case в большинстве компиляторов не сделает подобную же таблицу переходов? В условиях ведь сравнение на равенство константам, вполне ведь можно заменить на switch/case?
     
  11. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    gringoz0id
    1. Расскажи, в чем именно тут заключается ужоснах?
    2. Зачем оптимизировать этот код на скорость? Ты выполняешь его 50`000`000 раз в секунду?
    3. Ты не поверишь, но самый разумный способ, это таки воспользоваться бустом.
     
  12. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Ты под кайфом или как? Я думаю человек сам разберётся зачем ему оптимизировать и что использовать.
     
  13. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Booster
    Нет, все кончилось :dntknw:

    Вопрос ТС аналогичен вопросу "Посоны, у меня на первой передаче после 100 км/ч мотор чото сильно греется. Не знаете почему?".
     
  14. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Раунд № 1. По углам как обычно Ден и Бустер:)
    По теме: покажите, пожалуйста, типичный для данной программы вызов этой ф-ии. + учитывая то, что она работает с ошибками сети, то сколько должно быть этого много else if, чтобы они стали заметны по времени выполнения, даже если detectError вызывается после каждого вызовы сетефой ф-ии.
     
  15. 100gold

    100gold New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2010
    Сообщения:
    165
    В первую очередь надо подумать в сторону уже готового hashmap...

    Ну если первое почему-то не помогло, то
    Код (Text):
    1. char** textTable;
    2. size_t textTableSize;
    3.  
    4. textTableSize = MAX_ERROR;
    5. textTable = malloc(MAX_ERROR*sizeof(char*));
    6. for(size_t i=0; i<MAX_ERROR; ++i)
    7. {
    8.    textTable[i] = NULL;
    9. }
    10. textTable[WSANOTINITIALISED] = "text1";
    11. textTable[WSAENETDOWN] = "text2";
    12.  
    13. ...
    14. ...
    15. ...
    16.  
    17. *errCode = WSAGetLastError();
    18. if (*errCode < textTableSize)
    19. {
    20.    error = textTable[*errCode];
    21.    if (NULL == error)
    22.    {
    23.       error = "Unknown error";
    24.    }
    25. }
    26. else
    27. {
    28.    error = "Unknown error";
    29. }
    Если вдруг размер массива не устраивает, то можно попробовать разбить на 2 или более массивов, либо взять errCode по модулю, выбрав его таким образом, чтобы не было коллизий.
     
  16. gringoz0id

    gringoz0id New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2011
    Сообщения:
    6
    Booster
    100gold
    Благодарствую еще раз, буду ковырять в указанную сторону
     
  17. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    gringoz0id

    Зацени:

    Код (Text):
    1. #include <windows.h>
    2. #include <iostream>
    3. #include <boost/system/error_code.hpp>
    4.  
    5. int main()
    6. {
    7.     CreateWindowA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    8.     DWORD le = GetLastError();
    9.     std::cout << boost::system::error_code(le, boost::system::get_system_category()).message() << std::endl;
    10.     return 0;
    11. }
     
  18. gringoz0id

    gringoz0id New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2011
    Сообщения:
    6
    _DEN_
    Я тебя ща разочарую - в этом проекте по требованию заказчика не допускается использование сторонних библиотек. Вообще никаких. Даже MFC считается external dependency. Я бы рад использовать библиотеки типа буста, но нельзя.
    Посему мне жутко любопытно почему моя фраза: "без использования сторонних либ типа Boost'a" воспринялась тобой как "Ты не поверишь, но самый разумный способ, это таки воспользоваться бустом"?
    Что в данной фразе для тебя было непонятно?
    Если не понял, повторюсь - без использования сторонних библиотек, это все-таки, согласно семантике русского языка, означает "без использования". Как здесь можно было найти потайной смысл, хз.
    P.S. Крайне нехотя согласились на использование std::map, посмотрим, что получится, хотя видимо придется остановится на варианте, который предложил 100gold
     
  19. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Dmitry_Milk
    А вот хрен его знает - стандарт оптимизацию не гарантирует, а всё, что не в стандарте, может быть реализовано "как фишка ляжет".
     
  20. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    gringoz0id
    Тогда и я тебя разочарую - Boost.System вошла в STL три года назад. Или ты все еще пишешь на стандарте 10-ти летней давности?

    Лол, ну конечно, MFС - это самая ближайшая библиотека к C++.

    Библиотек типа буста нет.

    См. выше, C++2009.