C语言rand(),srand()函数真实性能分析

一直听人说c标准库的rand(), random()随机数产生函数性能极差。一直信以为真,今天做实验,发现并非如此

实验结论如下:

1. 系统自带的rand()和random()函数性能极高,大约相当于2.5次i++

2. rand()函数比random()函数性能稍差,差距大约在10%左右

3. Srand()函数性能非常差,大约比random()函数差了170倍左右,也就是约等于425次i++

4. rand的实现就是简单的乘法和取模,自己实现的随机数在性能上几乎无法超越系统自带的

5. 微软实现的随机数rand()很高效,srand()函数也很高效

实验结果如下图:

测试代码如下:

#include <stdio.h>
#include <stdint.h>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include<iostream>
using namespace std;

class Random
{
    public:
        static void srandom(int randSeedNum = 321);
        static int random();       
    private:
        static bool         m_bInit;    // 是否已初始化完成
        static int          m_count;    // 计数器
        static vector<int>  m_randSeeds;// 存放随机种子
};

bool Random::m_bInit = false;
int  Random::m_count = 0;
vector<int>  Random::m_randSeeds;
   
// 设置随机种子
void Random::srandom(int randSeedNum)
{
    // 先清空
    m_randSeeds.clear();
    // 再压入0,1,2,3 .... randSeedNum-2
    for(int i=0; i< randSeedNum; ++i){
        m_randSeeds.push_back( i );
    }
    // 打乱
    std::random_shuffle(m_randSeeds.begin(), m_randSeeds.end());
    // 标记已初始化完成
    m_bInit = true;
}

// 返回一个随机数
int Random::random()
{
    // 未初始化,则先初始化
    if(!m_bInit){
        srandom();
    }

    // 随机种子的vector长度
    static int size = m_randSeeds.size();
    
    // 每次自增后,得到随机数
    return 16777619 * m_randSeeds[m_count++%size];
}

// 微软的rand实现(POSIX.1-2001的样例)
static unsigned int next_start = 1;
int randMicro(void)
{
    next_start = next_start * 1103515245 + 12345;
    /* return (unsigned int)(next_start / 65536) % 32768;*/
    return (int)(next_start>>16) & RAND_MAX;
}
void srandMicro(unsigned int seed)
{
     /* And you *should* get a warning if sizes dont match
     */
    next_start = seed;
}

// 变量自增函数
int Inc()
{
    static int iCount = 0;
    return iCount++;
}

// 返回时间间隔,单位:毫秒
int GetPastTime(timeval* pStartTv)
{
    timeval  endTv;
    gettimeofday(&endTv, NULL);
    int uSecond = ((endTv.tv_sec - pStartTv->tv_sec) * 1000000 + endTv.tv_usec - pStartTv->tv_usec)/1000;
    return uSecond;
}

// i++函数1
void TestInc1(int count)
{
    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);
    
    // 自增count次
    for(int i=0; i<count; ++i){
        Inc();
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"i++函数1 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}

// i++函数2
void TestInc2(int count)
{
    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);

    static int icount = 0;
    for(int i=0; i<count; ++i){
        icount ++;
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"i++函数2 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}

// 自实现随机函数
void TestMyRandom(int count)
{
    // 随机种子,不计时
    Random::srandom();

    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);

    for(int i=0; i<count; ++i){
        Random::random();
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"自实现随机函数1 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}

// 微软实现的随机数
void TestMicroRandom(int count)
{
    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);

    for(int i=0; i<count; ++i){
        randMicro();
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"微软实现的随机数 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}

// 系统函数random
void TestRandom(int count)
{ 
    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);

    for(int i=0; i<count; ++i){
        random();
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"系统函数random 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}

// 系统函数rand
void TestRand(int count)
{ 
    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);

    for(int i=0; i<count; ++i){
        rand();
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"系统函数rand 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}

// 系统函数srand
void TestSrand(int count)
{ 
    // 起始时间
    timeval startTv;
    gettimeofday(&startTv, NULL);

    for(int i=0; i<count; ++i){
        srand(i);
    }

    // 结束时间
    int past = GetPastTime(&startTv);
    cout<<"系统函数srand 执行次数:"<<count<<" 消耗时间:"<<past<<"ms"<<endl;
}


int main(int argc, char** argv)
{
    // 执行1亿次
    int count = 100000000;
    
    cout<<"请选择要测试的函数:"<<endl;
    cout<<"1: 调用函数,静态变量自增"<<endl;
    cout<<"2: 静态变量自增"<<endl;
    cout<<"3: 自实现随机函数"<<endl;
    cout<<"4: 微软实现的随机数"<<endl;
    cout<<"5: 系统函数random()"<<endl;
    cout<<"6: 系统函数rand()"<<endl;
    cout<<"7: 系统函数srand()"<<endl;
    cout<<"请输入:";

    int choise = 1;
    cin>>choise;

    switch(choise)
    {
        case 1: // i++函数1
            TestInc1(count);
            break;
        case 2: // i++函数2
            TestInc2(count);
            break;
        case 3: // 系统函数random
            TestMyRandom(count);
            break;
        case 4: // 微软实现的随机数
            TestMicroRandom(count);
            break;
        case 5: // 系统函数random()
            TestRandom(count);
            break;
        case 6: // 系统函数rand()
            TestRand(count);
            break;
        case 7: // 系统函数srand()          
            TestSrand(count);
            break;
        default:
            cout<<"错误的类型"<<endl;
    }

    return 0;
}

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值