博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c库的rand/random随机数产生函数性能差?
阅读量:6176 次
发布时间:2019-06-21

本文共 3477 字,大约阅读时间需要 11 分钟。

有网文称c标准库的rand/random随机数产生函数性能极差。一直信以为真,但从没做过验证。最近因其他因缘,写了些代码专门验证rand/random的性能。结果大出意料,颠覆之前的成见。

结论如下:

1) rand/random性极佳。在64位机器上,其性能大约比简单自增略低30%(32位的自增比64位性能高出1倍以上)!

2) srand/srandom性能极差极差。绝对不能每次调用rand之前都调用srand。这么做不仅没必要,还会极大降低性能,性能只有调用rand的1%!!!

3) rand文档中提到的实现示例也实际实现存在差别,尤其是srand实现!

4) rand的实现起始就是简单的乘法和取模,简单的随机数实现在性能上几乎无法超越系统自带的标准实现!

5) 网上的东西很多真是不靠谱!!!

下面测试代码,代码在64/32位机器都能运行。

编译命令:g++ -o3 -o test random.cpp

1 #include 
2 #include
3 #include
4 #include
5 6 #include
7 #include
8 9 #include
10 11 12 #define NUM_RAND_SEED 100 13 14 15 class Random 16 { 17 public: 18 static int srandom(size_t randSeedNum = NUM_RAND_SEED); 19 20 static size_t random(); 21 22 private: 23 static bool m_bInit; 24 static size_t m_count; 25 static std::vector
m_randSeeds; 26 }; 27 28 bool Random::m_bInit = false; 29 size_t Random::m_count = 0; 30 std::vector
Random::m_randSeeds; 31 32 int Random::srandom( size_t randSeedNum ) 33 { 34 m_randSeeds.clear(); 35 36 for(size_t i=0; i< randSeedNum; ++i){ 37 m_randSeeds.push_back( i ); 38 } 39 40 std::random_shuffle(m_randSeeds.begin(), m_randSeeds.end()); 41 m_bInit = true; 42 43 printf("Random::srandom\n"); 44 return 0; 45 } 46 47 size_t Random::random() 48 { 49 if( ! m_bInit ) { 50 srandom(); 51 } 52 53 static size_t size = m_randSeeds.size(); 54 return 16777619 * m_randSeeds[ m_count ++ % size ]; 55 56 //return 16777619 * m_randSeeds[ m_count ++ % NUM_RAND_SEED ]; 57 //return 16777619 * m_randSeeds[ (m_count ++) & 0xffL ]; 58 } 59 60 // 简单随机数 61 int MyRandom() 62 { 63 static struct timeval tv; 64 static size_t iCount = 0; 65 66 tv.tv_usec += 54321; 67 if( tv.tv_usec > 1000000){ 68 tv.tv_usec -= 1000000; 69 } 70 if( iCount++ % 1000 == 0 ){ 71 gettimeofday(&tv, NULL); 72 } 73 74 return tv.tv_usec; 75 } 76 77 // 自增 78 int Inc() 79 { 80 static size_t iCount = 0; 81 82 return iCount++; 83 } 84 85 // 86 87 struct timeval stStartTv; 88 89 //return past time. uint: us 90 long PostTime(struct timeval *pstStartTv) 91 { 92 struct timeval stEndTv; 93 gettimeofday(&stEndTv, NULL); 94 struct timeval* pstCurrTv = &stEndTv; 95 96 long sec, usec = 0; 97 sec = pstCurrTv->tv_sec - pstStartTv->tv_sec; 98 if ((usec = pstCurrTv->tv_usec - pstStartTv->tv_usec) < 0) { 99 sec--;100 usec += 1000000;101 }102 usec += sec*1000000;103 104 return usec;105 }106 107 void LogPastTime(struct timeval *pstStartTv, const char* sStep)108 {109 long usec = PostTime(pstStartTv);110 111 printf("%s: Past time: %ld ms\n", sStep, usec / 1000);112 }113 114 #define STAT_NUM 100115 116 // 自增函数117 void TestInc(size_t count)118 {119 gettimeofday(&stStartTv, NULL);120 size_t arrCount[STAT_NUM] = { 0};121 printf("Test Inc...\n");122 123 for(size_t i=0; i
2){272 count = strtol(argv[2], NULL, 0);273 }274 275 if( argc < 2){276 printf("Usage: %s mode [count]\n", argv[0]);277 exit(0);278 }279 280 int mode = strtol(argv[1], NULL, 0);281 switch( mode )282 {283 case 0:284 TestInc(count);285 break;286 287 case 1:288 TestMyRandom(count);289 break;290 291 case 2:292 TestSimpleRandom(count);293 break;294 295 case 3:296 TestRandom(count);297 break;298 299 case 4:300 TestRand(count);301 break;302 303 case 5:304 TestRand2(count);305 break;306 307 case 6:308 TestInc2(count);309 break;310 311 312 default:313 printf("Unsupport mode: %d\n", mode);314 }315 316 return 0;317 }
http://www.cnblogs.com/zhenjing/archive/2012/06/10/c_random.html
你可能感兴趣的文章
exchange 2010 专题- 个人存档
查看>>
java
查看>>
Tomcat集群Cluster实现原理
查看>>
人人都应当控制的一些电脑操作技能
查看>>
百度echarts自定义主题使用
查看>>
ASP.NET MVC3中给DropDownList添加默认选项
查看>>
洛谷 1373 小a和uim之大逃离
查看>>
一不小心把win10的秘钥卸载了解决方法
查看>>
SilverLight之向后台请求数据-WebClient
查看>>
HDU Problem 1260 Tickets 【dp】
查看>>
STL map容器常用API
查看>>
队列的顺序存储---顺序队列
查看>>
Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示
查看>>
第三天
查看>>
connector for python
查看>>
等价类划分的应用
查看>>
Web Service(下)
查看>>
trigger()
查看>>
nvm 怎么安装 ?
查看>>
Java VM里的magic
查看>>