В C ++ у меня есть встроенная функция, которая содержит оператор switch-case. Я обнаружил, что когда запрограммирована какая-то ветвь speci c case , временные затраты на программу значительно возрастают, даже несмотря на то, что speci c case никогда не срабатывал во время выполнения.
Здесь показан пример кода:
#include <stdio.h>
#include <iostream>
#include <sys/time.h>
#include <string>
using namespace std;
enum Types {
T0 = 0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TS, TA, TB, TC
};
int64_t special(int64_t num, string str) {
char buf[16];
buf[0] = (num % 10) + '0';
buf[1] = (num % 10) + '0';
buf[2] = str.c_str()[0];
return atoi(buf);
}
inline int64_t common(int64_t base, int64_t num) {
return num + base;
}
inline int64_t myfunc(Types t, int64_t num) {
string str;
switch (t) {
case T0:
return 0;
break;
#define CASE_TYPE(tv, base) \
case tv: \
return common(base, num); \
break;
CASE_TYPE(T1, 1)
CASE_TYPE(T2, 2)
CASE_TYPE(T3, 3)
CASE_TYPE(T4, 4)
CASE_TYPE(T5, 5)
CASE_TYPE(T6, 6)
CASE_TYPE(T7, 7)
CASE_TYPE(T8, 8)
CASE_TYPE(T9, 9)
#undef CASE_TYPE
case TS:
// Comment out the following 3 lines increases performance
str = string((char*)&num, 4);
return special(num, str);
break;
// Comment out the above 3 lines increases performance
case TA:
case TB:
case TC:
return 0;
break;
}
return 0;
}
static const int LoopNum = 1000000000;
static inline int64_t now() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000 + (int64_t)tv.tv_usec / 1000;
}
// execution command line: ./test 1 1
int main(int argc, char *argv[])
{
Types t = (Types)atoi(argv[1]); // t = T1
int64_t num = (int64_t)atoi(argv[2]); // t = 1
int64_t total = 0;
int64_t start = now();
for (int i = 0; i < LoopNum; i++) {
total += myfunc(t, num);
}
cout << "Time Cost: " << now() - start << " ms" << endl;
cout << "Result: " << total << endl;
return 0;
}
В этой программе, когда строки в блоке case TS
закомментированы, производительность значительно возрастает:
- С блоком
case TS
: Стоимость времени = 2250 мс - Без блока
case TS
: Стоимость времени = 1492 мс
Программа компилируется и выполняется с помощью команды: g++ -o test -O2 test.cpp && ./test 1 1
. С помощью этой команды значения переменных в программе: t = T1
и num = 1
.
Проверено на Windows Subsystem for linux (Ubuntu 18.04)
с g++ 7.4.0
.
Что сбивает с толку то, что эта проблема не всегда возникает. У меня нет четких знаний о том, как писать такой код (но в приведенном выше примере действительно возникает эта проблема).
Согласно моим тестам, кажется, что проблема возникнет при некоторых из следующих условий:
- Программа в speci c case сложна. Например, когда программа содержит удаленный вызов процесса.
- специфицирует c регистр не последний регистр, или значение регистра не является наибольшим значением в перечислении.
Я действительно понятия не имею, как это происходит и как этого избежать. Может ли кто-нибудь дать adivce? Будет полезен либо механизм, либо обходной путь. Благодаря.