今天下班路上,想到了这个有意思的话题,回来让腾讯元宝帮我写了测试代码,不到5分钟,就测试出来结论了。
#include <iostream> #include <random> #include <chrono> #include <array> const int TOTAL = 1000000; // 每组测试100万次 // 方案一:ASCII计算法 void method1_rand() { for(int i=0; i<TOTAL; ++i) { char c1 = 'a' + (rand()%26); char c2 = 'a' + (rand()%26); char c3 = 'a' + (rand()%26); char c4 = 'a' + (rand()%26); // 防止优化 asm volatile("" : "+r"(c1), "+r"(c2), "+r"(c3), "+r"(c4)); } } // 方案二:数组索引法 void method2_rand() { const std::array<char,26> letters = { 'a','b','c','d','e','f','g','h','i','j','k','l','m', 'n','o','p','q','r','s','t','u','v','w','x','y','z'}; for(int i=0; i<TOTAL; ++i) { char c1 = letters[rand()%26]; char c2 = letters[rand()%26]; char c3 = letters[rand()%26]; char c4 = letters[rand()%26]; asm volatile("" : "+r"(c1), "+r"(c2), "+r"(c3), "+r"(c4)); } } // C++11版本测试(以方案一为例) void method1_mt19937() { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dist(0,25); for(int i=0; i<TOTAL; ++i) { char c1 = 'a' + dist(gen); char c2 = 'a' + dist(gen); char c3 = 'a' + dist(gen); char c4 = 'a' + dist(gen); asm volatile("" : "+r"(c1), "+r"(c2), "+r"(c3), "+r"(c4)); } } int main() { srand(time(nullptr)); // 初始化传统随机种子 auto test = [](auto func, const char* name) { using namespace std::chrono; double avg = 0; // 预热 func(); // 正式测试 for(int i=0; i<5; ++i) { auto start = high_resolution_clock::now(); func(); auto end = high_resolution_clock::now(); avg += duration_cast<microseconds>(end-start).count(); } std::cout << name << " avg: " << avg/5 << " us\n"; }; test(method1_rand, "ASCII(rand)"); test(method2_rand, "array(rand)"); test(method1_mt19937, "c++11_mt19937"); // 可添加C++11版本测试 }
腾讯元宝给出的建议:
关键发现:
传统rand方法效率更高:两种方案的性能差异在3%以内,ASCII计算法稍快
C++11随机库较慢:MT19937虽然随机性更好,但耗时是传统方法的2倍以上
内存访问影响:数组索引法的缓存局部性优势在少量数据时不明显
四、选择建议
游戏/简单应用:推荐ASCII计算法,代码简洁且效率高
密码学/科学计算:选择C++11随机库+数组索引法,保证随机质量
嵌入式系统:优先ASCII计算法,减少内存占用
运行效率:
ASCII(rand) avg: 32290.4 us
array(rand) avg: 33703.2 us
c++11_mt19937 avg: 49786.6 us
系统当前共有 442 篇文章