编程实现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了一下。好吧,哭一会去。

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

时间: 2024-12-10 05:40:54

编程实现memset的相关文章

linux服务器开发二(系统编程)--线程相关

线程概念 什么是线程 LWP:Light Weight Process,轻量级的进程,本质仍是进程(在Linux环境下). 进程:独立地址空间,拥有PCB. 线程:也有PCB,但没有独立的地址空间(共享). 进程与线程的区别:在于是否共享地址空间. 独居(进程). 合租(线程). Linux下: 线程:最小的执行单位. 进程:最小分配资源单位,可看成是一个线程的进程. 安装man文档 sudo apt-get install glibc-doc sudo apt-get install manp

Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录 (四) 一起学 Unix 环境高级编程 (APUE) 之 系统数据文件和信息 (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境 (六) 一起学 Unix 环境高级编程 (APU

基于TCP协议之——socket编程

一. 套接字(socket) socket英文为插座的意思,也就是为用户提供了一个接入某个链路的接口.而在计算机网络中,一个IP地址标识唯一一台主机,而一个端口号标识着主机中唯一一个应用进程,因此"IP+端口号"就可以称之为socket. 两个主机的进程之间要通信,就可以各自建立一个socket,其实可以看做各自提供出来一个"插座",然后通过连接上"插座"的两头也就是由这两个socket组成的socket pair就标识唯一一个连接,以此来表示网

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.android实现自绘日期选择控件 目的: 通过一个相对复杂的自定义自绘控件来分享: 1.ios以及android自定义自绘控件的开发流程 2.objc与c/c++混合编程 3.android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作

linux下socket编程-进程间通信

一.什么是Socket Socket接口是TCP/IP网络通信的API,Socket接口定义了许多函数或例程,可以用它们来开发TCP/IP网络上的应用程序. Socket类型有两种:流式Socket (SOCK_STREAM)和数据报式Socket(SOCK_DGRAM).流式是一种面向连接针对于面向连接的TCP服务应用:数据报式Socket是一种无连接针对无连接的UDP服务应用.sock通信的基本过程如下: 二.Socket建立 程序可以调用Socket函数建立socket,该函数返回一个类似

嵌入式系统编程和调试技巧

嵌入式系统的开发,软件的运行稳定可靠是非常重要的.在芯片中,软件是没有质量的,但软件的质量可以决定一颗芯片的成败.芯片设计中,性能能否满足设计要求,除了硬件设计.软硬件配合的设计技巧,对于软件来说,编程的一些技术和技巧同样重要. 本文讲述我在芯片固件开发过程中使用的一些编程调试技巧.针对在嵌入式系统开发中常见的问题,如实时系统下的同步问题,动态内存分配的内存泄漏问题,如何在编程阶段预防BUG出现,调试阶段如何及时发现问题和定位问题.总结下经验,目的是开发一个稳定运行的固件,提高开发效率,提高运行

hdu 4542 数论 + 约数个数相关 腾讯编程马拉松复赛

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4542 小明系列故事--未知剩余系 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 889    Accepted Submission(s): 207 Problem Description "今有物不知其数,三三数之有二,五五数之有三,七七数之有

(一)理解网络编程和套接字

学习<TCP/IP网络编程> 韩 尹圣雨 著 金国哲 译 套接字类似电话 一.服务器端套接字(listening套接字)---接电话套接字 ①调用socket函数---安装电话机 #include <sys/socket.h> int socket(int domain, int type, int protocol); //成功时返回文件描述符,失败时返回-1 ②调用bind函数---分配电话号码 #include <sys/socket.h> int bind(in

华为C语言编程规范

DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd.版权所有 侵权必究All rights reserved密级:confidentiality levelDKBA 2826-2011.52011-06-02 华为机密,未经许可不得扩散 Huawei Confidential 第2页,共61页Page 2 , Total61修订声明Revision