2014-09-19 2 views
0

Я пытаюсь оптимизировать код, который мне пришлось реорганизовать. Код без каких-либо оптимизаций будет иметь некоторые операторы switch. Если ошибка происходит в распределительном заявлении об ошибке возвращается к вызывающему методу, например:Оптимизация конструкций коммутаторов - как избежать добавления if-clauses

switch(var) 
{ 
    case VAL1: 
    //do something... 
    break; 
    case VAL2: 
    //do something else... 
    //... 
    case VAL3: 
    if (...) // there is any case that can cause error 
    { 
     return error1; 
    } 
    break; 
    case VAL4: 
    if (...) // there is any case that can cause error 
    { 
     return error2; 
    } 
    break; 
    case VAL5: 
    if (...) // there is any case that can cause error 
    { 
     return error1; 
    } 
    break; 
    //and so on... 
    default: 
     break; 
} 

Я рефакторинг кода, поэтому я не возвращаю ошибку в операторе переключателя, но вместо этого я маркировкой что произошла ошибка в переменном:

int error_type = -1; 

switch(var) 
{ 
    case VAL1: 
    //do something... 
    break; 
    case VAL2: 
    //do something else... 
    //... 
    case VAL3: 
    if (...) // there is any case that can cause error 
    { 
     error_type = error1; 
    } 
    break; 
    case VAL4: 
    if (...) // there is any case that can cause error 
    { 
     error_type = error2; 
    } 
    break; 
    case VAL5: 
    if (...) // there is any case that can cause error 
    { 
     error_type = error1; 
    } 

    break; 
    //and so on... 
    default: 
     break; 
} 

if (error_type != -1) 
     return error_type; 

проблема возникает, когда нет никакой ошибки, потому что мы добавляем другое, если заявление, которое может вызвать проблемы с производительностью, если метод вызывается много раз в секунду. Я бы не стал проверять условие каждый раз. Есть ли предложения по улучшению этого кода? Любые трюки с реорганизацией коммутатора?

// EDIT: Я знаю, что этот пример может выглядеть немым (поскольку рефакторинг там не выглядит очень полезным), но фактический код, который я рефакторинг, действительно нуждается в нем (верьте мне), поэтому я стараюсь не потерять производительность в конечном коде.

+1

Каковы возможные значения для var? –

+1

Есть ли общность в условиях if? –

+0

"* Я хотел бы избегать проверки состояния каждый раз. *" Какой? – alk

ответ

2

Общее правило состоит в том, что операторы switch могут быть заменены поисковыми таблицами или массивами. Одно из преимуществ таблиц заключается в том, что их можно легко обновить с минимальными затратами на производительность и небольшими изменениями функции поиска (движка).

Вот некоторые идеи:

Если есть шаблон для условной проверки, поместить переменные в таблицу. Пусть двигатель выполнит проверку.

Поместите указатель функции в таблицу, чтобы выполнить проверку. Если указатель функции NULL, то проверки нет.

+0

Однако таблица 'if (table [x]! = NULL] [x]();' над 'switch (x)' с 'if (...)' является вероятным y «отрицательный» или «нулевой» - если вы не можете каким-то образом устранить сложный 'if (...)' - однако, я сомневаюсь.Существует действительно случай использования таблицы вместо 'switch', но я не думаю, что это один из них. –

+0

@MatsPetersson: В этом случае переход на поиск таблицы может не повысить производительность, но OP также упоминает проблему обслуживания, всегда добавляющую случаи в оператор 'switch'. Таблица поиска хороша для уменьшения проблем обслуживания. –

+0

Для меня это примерно такое же усилие ... –