码迷,mamicode.com
首页 > 其他好文 > 详细

编程实现memset

时间:2015-07-28 23:11:28      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:memset实现

——来看看源码的权威
memset主要用于为新申请的内存进行初始化,它是对较大的结构体和数组进行清零操作的一种最快方法。
函数原型:void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节用ch填充,并返回s。
对于这些最基本的函数,总有一种冲动想知道其是怎么实现的。
下面就是根据源码而来的memset实现:

void* memset(void* dst,int val, size_t count)
{
    void* ret = dst;
    while(count--)
    {
        *(char*)dst = (char)val;
        dst = (char*)dst + 1; //移动一个字节
    }
    return ret;
}

下面是修改后的实现:

void* memset(void* dst,int val, size_t count)
{
    char* tmpdst = (char*)dst;
    char tmpval = (char)val;
    while(count--)
    {
        *tmpdst++ = tmpval;
    }
    return dst;
}

总是感觉下面修改后的实现要比上面源码实现的效率要高,不用多次类型转换。其实不然,编译器可能将上面代码优化的比下面还好。
来吧,测试下看看:
测试代码:

#include <iostream>
#include <string>
#include <ctime>
using namespace std;

void* memset1(void* dst,int val, size_t count)
{
    void* ret = dst;
    while(count--)
    {
        *(char*)dst = (char)val;
        dst = (char*)dst + 1;
    }
    return ret;
}

void* memset2(void* dst,int val, size_t count)
{
    char* tmpdst = (char*)dst;
    char tmpval = (char)val;
    while(count--)
    {
        *tmpdst++ = tmpval;
    }
    return dst;
}

int _tmain(int argc, _TCHAR* argv[]){
    int* a = new int[100000000];
    size_t count = sizeof(int)*100000000;
    clock_t start,finish;
    long i = 100000L;
    double duration;
    int circle = 10;
    while(circle--)
    {
        start = clock();
        memset1(a,1,count);
        finish = clock();
        duration = (double)(finish - start)/CLOCKS_PER_SEC;
        cout<< "memset1: " << duration << endl;

        start = clock();
        memset2(a,2,count);
        finish = clock();
        duration = (double)(finish - start)/CLOCKS_PER_SEC;
        cout<< "memset2: " << duration << endl;
    }
    system("pause");
    return 0;
}

结果:
技术分享
结果说明二者都是在上下浮动,但是源码方法普遍比优化后的时间要小。

感觉还是不行,用更精确的方法测试了下。

int _tmain(int argc, _TCHAR* argv[]){
    int* a = new int[100000000];
    size_t count = sizeof(int)*100000000;
    LARGE_INTEGER frequency, start, finish;
    long i = 100000L;
    int circle = 10;
    while(circle--)
    {   
        QueryPerformanceFrequency(&frequency);
        QueryPerformanceCounter(&start);            
        memset1(a,1,count);
        QueryPerformanceCounter(&finish);           
        cout<< "memset1: " <<(double)(finish.QuadPart-start.QuadPart)/frequency.QuadPart<<endl;

        QueryPerformanceFrequency(&frequency);
        QueryPerformanceCounter(&start);            
        memset2(a,2,count);
        QueryPerformanceCounter(&finish);           
        cout<< "memset2: " <<(double)(finish.QuadPart-start.QuadPart)/frequency.QuadPart<<endl;
    }
    system("pause");
    return 0;
}

结果:
技术分享
结果也是讽刺,竟然优化后的结果80%都比没有优化的时间长,说明优化反倒还效率低了。

最后,不得不感叹源代码就是源代码,极致就是极致,虽然结果只有很小的差距,但是结论却是一致的,差之毫厘谬以千里!自以为是地“优化”现在变成了一种讽刺。(此处略去N个字)。还有我在(http://blog.csdn.net/z702143700/article/details/47107701)这篇博客中也做了优化,当时还bb了一下。好吧,哭一会去。

版权声明:本文为博主原创文章,未经博主允许不得转载。

编程实现memset

标签:memset实现

原文地址:http://blog.csdn.net/z702143700/article/details/47112971

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!