У нас есть карта типов сообщений в список сообщений. Учитывая критичный к производительности кусок кода, такой как это:
struct row_t {
int message_type; //0,1,2,3,4,5
};
map<int, vector<row_t>> message_map;
for (auto x : message_map) {
int message_type = x.first;
vector<row_t> message_rows = x.second;
for (row_t row : message_rows) {
//LARGE CODE CHUNK
switch(row.message_type) { //same as switch(message_type)
case 0:
add_0_to_database();
break;
case 1:
add_0_to_database();
break;
//...
default:
break;
}
}
}
Оператор switch будет выполняться на каждой итерации внутреннего цикла, даже если каждый элемент в message_rows имеет одинаковый тип.
Эту проблему можно устранить, запустив оператор switch только один раз до запуска внутреннего цикла:
for (auto x : message_map) {
int message_type = x.first;
vector<row_t> message_rows = x.second;
switch(message_type) {
case 0:
for (row_t row : message_rows) {
//LARGE CODE CHUNK
add_0_to_database(row);
}
break;
case 1:
for (row_t row : message_rows) {
//LARGE CODE CHUNK
add_1_to_database(row);
}
break;
//...
default:
break;
}
}
Но теперь у нас есть несколько избыточных внутренних циклов, и код "LARGE CODE CHUNK" необходимо дублировать несколько раз.
Мой вопрос: могут ли современные компиляторы (в частности, g ++) оптимизировать версию 1, чтобы быть такой же эффективной, как версия 2?
Или мне следует перейти на версию 2 и, возможно, рассмотреть возможность использования какого-либо другого метода для удаления избыточности, например, установить указатель функции на add_{0/1}_to_database
в операторе switch и затем использовать указатель на функцию в цикле?