使用达夫设备读取一个char型文件,每次读1个字节和4个字节的速度比较

1. 知识准备

     1)计算函数的运行时间

           要想获取一个函数的运行时间,可直接在该函数的运行前后,添加一个计时函数,但可能会存在一个问题,大多数函数运行时间较短,因此需要一个精度非常大的函数,经查找,最终选用windows.h下的函数,通过时钟来计算时间差。

           先通过QueryPerformanceFrequency()获取时钟周期数;

          再通过QueryPerformanceCounter()获取时钟计数;

          计算函数运行所用的总时钟数,再除以时钟周期数,即可计算出相应时间。单位为微妙

    2)通过指针复制字节

           定义指针时,需要指定指针类型,如char、int ,如int * a,变量a 表示4个字节,char * b,变量b表示1个字节。

int *a;
int *b;
*a=*b;

这个操作,是4个字节的
如果把int 改为char,则这个操作是一个字节的

2.提出问题

利用这个特性,产生如下想法:
在达夫设备的基础上,对于同一个char型文件,通过指针赋值 的方式,把每次复制1个字节变成每次复制4个字节,是否会把速度提得更快呢?

当然,这种方式可能会产生以下问题:

 该char型文件的大小,若不是4的倍数,剩下的“尾巴”该如何处理?

3.解决方式

#include <stdio.h>
#include <time.h>
#include <windows.h>

#define N 1000

double duration;
void duffC_device(char *from, char *to, int count);
void duffI_device(char *from, char *to, int count);
LARGE_INTEGER m_nFreq;
LARGE_INTEGER m_nBeginTime;
LARGE_INTEGER m_nEndTime;

int main(int argc, char** argv) {
	char str[N]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','0','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
				 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
	char cstr[N]={0};

	QueryPerformanceFrequency(&m_nFreq); // 获取时钟周期
	QueryPerformanceCounter(&m_nBeginTime); // 获取时钟计数
		duffC_device(str,cstr,N);
	QueryPerformanceCounter(&m_nEndTime);
	//	for(int i=0;i<N;i++)                 //将其打印输出,测试内容和数量是否复制正确 
	//		printf("%c ",cstr[i]);
	printf("\nticks 1= %lf\n", (double)(m_nEndTime.QuadPart-m_nBeginTime.QuadPart)*1000/m_nFreq.QuadPart);
	
	QueryPerformanceCounter(&m_nBeginTime); // 获取时钟计数
		duffI_device(str,cstr,N);
	QueryPerformanceCounter(&m_nEndTime);
	//for(int i=0;i<N;i++)
	//		printf("%c ",cstr[i]);
	printf("\nticks 4= %lf\n", (double)(m_nEndTime.QuadPart-m_nBeginTime.QuadPart)*1000/m_nFreq.QuadPart);
//    system("pause"); 
	return 0;
}


void duffC_device(char *from, char *to, int count) //每次读取1个字节 
{
        int n = (count + 7) / 8;

        switch(count % 8) {
            case 0: do { *to++ = *from++;
                        case 7: *to++ = *from++;
                        case 6: *to++ = *from++;
                        case 5: *to++ = *from++;
                        case 4: *to++ = *from++;
                        case 3: *to++ = *from++;
                        case 2: *to++ = *from++;
                        case 1: *to++ = *from++;
                    } while(--n > 0);
        }
}

void duffI_device(char *from, char *to, int count)
{
	int rem=count%4;                  // 处理余4的“尾巴部分”(这部分不够一个int字节,否则越界,需提前处理) 
	switch(rem){
		 case 3: *to++ = *from++;
         case 2: *to++ = *from++;
         case 1: *to++ = *from++;
	}
	
	int *dFrom=(int *)(from);        //用一个int型指针,指向4个char字节 
	int *dTo=(int *)(to);
	count=count/4;					//char 用int指针表示后,总数量变为count/4(记得除4哦,否则每次都会多读12个字节) 
    int n = (count + 7) / 8;      
	switch(count % 8) {
		case 0: do { *dTo++ = *dFrom++;
			case 7: *dTo++ = *dFrom++;
                case 6: *dTo++ = *dFrom++;
                case 5: *dTo++ = *dFrom++;
                case 4: *dTo++ = *dFrom++;
                case 3: *dTo++ = *dFrom++;
            case 2: *dTo++ = *dFrom++;
            case 1: *dTo++ = *dFrom++;
            } while(--n > 0);
        }
}

4.测试结果

经测试,随着复制数量的增大,两者复制速度差也越来越大

 

这样的处理还是有一些效果的,尤其是在调试的时候,两种方法所循环次数以及赋值次数的比较,后者真的是很爽了!

哈哈,不足之处还请各位佬大多多指教!٩(๑>◡<๑)۶

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值