Is switch case faster if using smaller numbers?
我想知道,如果我在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <iostream> #include <iomanip> #include <chrono> int main() { uint32_t f = 0x12345688; std::chrono::time_point<std::chrono::system_clock> start, end; int i = -1; start = std::chrono::system_clock::now(); switch (f) { case 0x1234500 : i = 0; break; case 0x1234522 : i = 2; break; case 0x1234555 : i = 5; break; case 0x1234588 : i = 8; break; default : break; } end = std::chrono::system_clock::now(); std::chrono::duration<double> elapsed_seconds = end-start; std::cout <<"elapsed time:" << elapsed_seconds.count() <<"s "; int j = -1; start = std::chrono::system_clock::now(); switch (f & 0xf) { case (0x1234500 & 0xf) : j = 0; break; case (0x1234522 & 0xf) : j = 2; break; case (0x1234555 & 0xf) : j = 5; break; case (0x1234588 & 0xf) : j = 8; break; default : break; } end = std::chrono::system_clock::now(); elapsed_seconds = end-start; std::cout <<"elapsed time:" << elapsed_seconds.count() <<"s "; return 0; } |
第二个开关箱似乎总是更快。
案例中的小数字使陈述更快(案例之间的"差距"是相同的)有什么原因吗?
这种基准测试方法毫无意义,因为编译器可以静态地确定两种情况之间的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | start = std::chrono::system_clock::now(); switch (f) { case 0x1234500 : i = 0; break; case 0x1234522 : i = 2; break; case 0x1234555 : i = 5; break; case 0x1234588 : i = 8; break; default : break; } end = std::chrono::system_clock::now(); std::chrono::duration<double> elapsed_seconds = end-start; std::cout <<"elapsed time:" << elapsed_seconds.count() <<"s "; // i = -1; this line isn't needed, the value isn't used, lets optimize it away start = std::chrono::system_clock::now(); // Oh great, we already know the value of i // Because nothing in the previos code could have affected f // i will get the same value as it did above, and we removed i = -1 // So lets optimize away this pointless code here end = std::chrono::system_clock::now(); elapsed_seconds = end-start; |
您可以尝试将
测试之间的
最好的方法可能是从文件或用户输入中读取常量
一般情况下:在这样做基准测试时,一定要分解代码,以验证您的测试不是胡说八道。
对于性能来说,最重要的是数字是连续的。这是因为编译器可以使用该值来索引内存地址,该地址指定开关应跳转到何处来处理有问题的情况。大的空白使得索引不可能,因为它会跳得很远,编译器必须插入大量的空代码来填充未使用的空间。
小数字可以使它稍微快一点-您可能只保存一条指令,因为编译器可以减去然后仍然可以使用索引。
以上所有内容都依赖于编译器。一个愚蠢的编译器可能根本不会使用索引。