Друзиа, "обращаюсь не корысти ради, а токмо воли пославшей мя жоны" (с) В наследство достался блок кода, состоящий из пары сотен операторов "switch" и "else if" Что-то типа такого: Код (Text): void detectError(int* errCode) { char * error; *errCode = WSAGetLastError(); if ( *errCode == WSANOTINITIALISED ) // error = '""; else if ( *errCode == WSAENETDOWN ) // error = '""; else if ( *errCode == WSAEAFNOSUPPORT ) // error = '""; .......... много else if Как можно избавиться от этого ужоснаха, оптимизировать код, увеличить скорость исполнения штатными средствами, без использования сторонних либ типа Boost'a? Буду очень признателен любым дельным предложениям и пинкам в нужную сторону.
gringoz0id Если оптимизировать по скорости, то этот код лучше вообще не трогать. Или ошибок так много, что их обработка самое узкое место программы?!
Black_mirror Ошибок немного на самом деле. Эта функция является частью системы логирования и автор, видимо, хотел предусмотреть все возможные варианты. Mikl___ Это Boost За ссылку спасибо, изучаю
gringoz0id Ну и зачем ее тогда оптимизировать, если и ошибки возникают редко и само логирование наверняка пожирает намного больше времени, чем все эти ифы? Если эта функция должна обрабатывать не только ошибки, но и штатные отказы типа WSAEWOULDBLOCK и т.п., то их можно проверять в первую очередь с выходом по return
Самый быстрый - завернуть каждую ветку ELSEIF в функцию, сделать таблицу указателей на функции, где errCode - порядковый номер элемента в таблице, потом читать указатель из таблицы и вызывать по нему функцию. Если эти коды сильно разреженные, хреначим таблицу соответствий "код ошибки - указатель на функцию", сортируем и ищем в ней бинарным поиском.
А разве switch/case в большинстве компиляторов не сделает подобную же таблицу переходов? В условиях ведь сравнение на равенство константам, вполне ведь можно заменить на switch/case?
gringoz0id 1. Расскажи, в чем именно тут заключается ужоснах? 2. Зачем оптимизировать этот код на скорость? Ты выполняешь его 50`000`000 раз в секунду? 3. Ты не поверишь, но самый разумный способ, это таки воспользоваться бустом.
_DEN_ Ты под кайфом или как? Я думаю человек сам разберётся зачем ему оптимизировать и что использовать.
Booster Нет, все кончилось Вопрос ТС аналогичен вопросу "Посоны, у меня на первой передаче после 100 км/ч мотор чото сильно греется. Не знаете почему?".
Раунд № 1. По углам как обычно Ден и Бустер По теме: покажите, пожалуйста, типичный для данной программы вызов этой ф-ии. + учитывая то, что она работает с ошибками сети, то сколько должно быть этого много else if, чтобы они стали заметны по времени выполнения, даже если detectError вызывается после каждого вызовы сетефой ф-ии.
В первую очередь надо подумать в сторону уже готового hashmap... Ну если первое почему-то не помогло, то Код (Text): char** textTable; size_t textTableSize; textTableSize = MAX_ERROR; textTable = malloc(MAX_ERROR*sizeof(char*)); for(size_t i=0; i<MAX_ERROR; ++i) { textTable[i] = NULL; } textTable[WSANOTINITIALISED] = "text1"; textTable[WSAENETDOWN] = "text2"; ... ... ... *errCode = WSAGetLastError(); if (*errCode < textTableSize) { error = textTable[*errCode]; if (NULL == error) { error = "Unknown error"; } } else { error = "Unknown error"; } Если вдруг размер массива не устраивает, то можно попробовать разбить на 2 или более массивов, либо взять errCode по модулю, выбрав его таким образом, чтобы не было коллизий.
gringoz0id Зацени: Код (Text): #include <windows.h> #include <iostream> #include <boost/system/error_code.hpp> int main() { CreateWindowA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); DWORD le = GetLastError(); std::cout << boost::system::error_code(le, boost::system::get_system_category()).message() << std::endl; return 0; }
_DEN_ Я тебя ща разочарую - в этом проекте по требованию заказчика не допускается использование сторонних библиотек. Вообще никаких. Даже MFC считается external dependency. Я бы рад использовать библиотеки типа буста, но нельзя. Посему мне жутко любопытно почему моя фраза: "без использования сторонних либ типа Boost'a" воспринялась тобой как "Ты не поверишь, но самый разумный способ, это таки воспользоваться бустом"? Что в данной фразе для тебя было непонятно? Если не понял, повторюсь - без использования сторонних библиотек, это все-таки, согласно семантике русского языка, означает "без использования". Как здесь можно было найти потайной смысл, хз. P.S. Крайне нехотя согласились на использование std::map, посмотрим, что получится, хотя видимо придется остановится на варианте, который предложил 100gold
Dmitry_Milk А вот хрен его знает - стандарт оптимизацию не гарантирует, а всё, что не в стандарте, может быть реализовано "как фишка ляжет".
gringoz0id Тогда и я тебя разочарую - Boost.System вошла в STL три года назад. Или ты все еще пишешь на стандарте 10-ти летней давности? Лол, ну конечно, MFС - это самая ближайшая библиотека к C++. Библиотек типа буста нет. См. выше, C++2009.