您的位置:首页 > 编程语言 > C语言/C++

C语言数组和链表删除元素速度比较

2016-10-15 21:30 393 查看
前断时间我做个实验对比了java数组和链表插入和删除元素时间对比,结果是数组完胜,后来发现不止我一个人得出了这样的结果[链接](http://blog.csdn.net/qq_21544879/article/details/51909473),今天用C语言再次做了数组和链表删除元素测试,结果没有给我惊喜,链表完胜。但也有一个新的发现,最初在删除数组元素时,我用for循环把数组元素一个个往前移,后来试了下按字节拷贝,最后还试了一下用系统的memcpy函数来往前移动数组元素。结果很是意外,memcpy也是按字节来拷贝的,按理说其速度应该与自己实现的按字节拷贝差不多,最后测试结果是**memcpy > for循环拷贝 > 自己实现按字节拷贝**。其速度相差都是好几倍,最后我对这三种方式拷贝数组做了测试,测试代码在下面。


贴下我的测试代码,欢迎指出错误:

实验一,数组和链表随机删除元素速度测试:

实验数据为20W个整数, 测试系统为ubuntu16.04, 先给数组和链表各填充20W个元素,然后随机删除元素,删除元素为随机数对数组或链表剩余元素数量取余,防止越界。

//测试结果
/*
线性表删除运行耗时26729 ms
链性表删除运行耗时0 ms
线性表删除运行耗时27650 ms
链性表删除运行耗时0 ms
线性表删除运行耗时26710 ms
链性表删除运行耗时0 ms
线性表删除运行耗时26828 ms
链性表删除运行耗时0 ms
线性表删除运行耗时26698 ms
链性表删除运行耗时0 ms

*/

#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <memory.h>

#define SIZE 200000 //20W

//链表节点
typedef struct LNode {
int elem;
struct LNode *next;
} LNode;

//链表
typedef struct {
LNode *list;
long length;
}LinkList;

//线性表
typedef struct {
int *elems;
long length;
long listSize;
}SqList;

//初始化元素
void initSqList(SqList *sqList);
void initLinkList(LinkList *linkList);

//打印
void printSqlist(SqList *sqList);
void printLinkList(LinkList *linkList);

//删除
void sqListDel(SqList *sqList, long pos);
void linkListDel(LinkList *linkList, long pos);

//线性表和链表删除耗时比较
void delDiff(SqList *sqList, LinkList *linkList);

//插入耗时比较
void insertDiff(SqList sqList, LinkList linkList);

//线性表和链表随机删除和插入元素比较
int main() {
LinkList *linkList = NULL;
SqList *sqList = NULL;

linkList = (LinkList *) malloc(sizeof(LinkList));
linkList->list  = (LNode *) malloc(sizeof(LNode));
assert(linkList->list != NULL);
linkList->list->next = NULL;

sqList = (SqList *) malloc(sizeof(SqList));
if(!sqList || !linkList) {
printf("分配空间失败");
return -1;
}

int i = 0;
for(; i < 5; i++) {
initSqList(sqList);
/* printSqlist(sqList); */
initLinkList(linkList);
/* printLinkList(linkList); */
delDiff(sqList, linkList);
}

return 0;
}

void initSqList(SqList *sqList) {
assert(sqList != NULL);
sqList->elems = (int *) malloc(sizeof(int) * SIZE);
if(!sqList->elems) {
printf("分配数组空间失败");
}
long i = 0;
for(; i < SIZE; i++) {
sqList->elems[i] = i;
}
sqList->length = SIZE;
sqList->listSize = SIZE;
}

void printSqlist(SqList *sqList) {
assert(sqList != NULL);
long i = 0;
for(; i < sqList->length; i++) {
printf("%d, ", sqList->elems[i]);
}
printf("打印完成\n");
}

void initLinkList(LinkList *linkList) {
assert(linkList != NULL && linkList -> list != NULL);
LNode *tail = linkList->list;
long i = 0;
for(; i < SIZE; i++) {
LNode *temp = (LNode *) malloc(sizeof(LNode));
temp->elem = i;
tail->next = temp;
tail = temp;
}
linkList->length = SIZE;

}

void printLinkList(LinkList *linkList) {
assert(linkList != NULL && linkList->list != NULL);
LNode *temp = linkList -> list;
while(temp->next != NULL) {
printf("%d, ", temp->next->elem);
temp = temp->next;
}
printf("打印完成\n");
}

void sqListDel(SqList *sqList, long pos) {
assert(sqList != NULL && sqList->elems != NULL);
if(pos < 0 || pos >= sqList->length) {
printf("pos: %ld 超出界限\n", pos);
return;
}

long i = pos;
for(; i < sqList->length - 1; i++) {
sqList -> elems[i] = sqList->elems[i + 1];
}
sqList->length--;

}

void linkListDel(LinkList *linkList, long pos) {
assert(linkList != NULL && linkList->list != NULL);
if(pos < 0 || pos >= linkList->length) {
printf("pos: %ld 超出界限\n", pos);
return;
}

LNode *temp = linkList->list;
long i = 0;
for(; i < pos; i++) {
temp = temp->next;
}

LNode *delNode = temp->next;
temp->next = temp->next->next;
free(delNode);
linkList->length--;
}

void delDiff(SqList *sqList, LinkList *linkList) {
struct timeval startTime, endTime;
srand((unsigned)time(0));
long ran_num;
long i = 0;
gettimeofday(&startTime, NULL);
for(; i < SIZE; i++) {
ran_num = rand() % (SIZE - i);
sqListDel(sqList, ran_num);
}
gettimeofday(&endTime, NULL);
printf("线性表删除运行耗时%ld ms\n", (endTime.tv_sec * 1000  + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000));

gettimeofday(&startTime, NULL);
for(; i < SIZE; i++) {
ran_num = rand() % (SIZE - i);
linkListDel(linkList, ran_num);
}
gettimeofday(&endTime, NULL);
printf("链性表删除运行耗时%ld ms\n", (endTime.tv_sec * 1000  + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000));
}


实验二,数组拷贝元素测试:

/*
实验结果
for循环拷贝数组200000000个元素耗时1154 ms
字节拷贝数组200000000个元素耗时1764 ms
memcpy拷贝数组200000000个元素耗时182 ms

for循环拷贝数组200000000个元素耗时517 ms
字节拷贝数组200000000个元素耗时1764 ms
memcpy拷贝数组200000000个元素耗时178 ms

for循环拷贝数组200000000个元素耗时514 ms
字节拷贝数组200000000个元素耗时1771 ms
memcpy拷贝数组200000000个元素耗时179 ms

for循环拷贝数组200000000个元素耗时516 ms
字节拷贝数组200000000个元素耗时1770 ms
memcpy拷贝数组200000000个元素耗时177 ms

for循环拷贝数组200000000个元素耗时515 ms
字节拷贝数组200000000个元素耗时1777 ms
memcpy拷贝数组200000000个元素耗时178 ms
*/
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <memory.h>

#define SIZE 200000000 //200M

//线性表
typedef struct {
int *elems;
long length;
long listSize;
}SqList;

//初始化元素
void initSqList(SqList *sqList);

//打印
void printSqlist(SqList *sqList);
void copyDiff(SqList *sqList);

//三种拷贝方法
void copyByFor(SqList *star, SqList *end, int len);
void copyByBit(SqList *star, SqList *end, int len);
void copyByMem(SqList *star, SqList *end, int len);

//线性表和链表随机删除和插入元素比较
int main() {
SqList *sqList = NULL;

sqList = (SqList *) malloc(sizeof(SqList));
if(!sqList) {
printf("分配空间失败");
return -1;
}

initSqList(sqList);
copyDiff(sqList);

return 0;
}

void initSqList(SqList *sqList) {
assert(sqList != NULL);
sqList->elems = (int *) malloc(sizeof(int) * SIZE);
if(!sqList->elems) {
printf("分配数组空间失败");
}
long i = 0;
for(; i < SIZE; i++) {
sqList->elems[i] = i;
}
sqList->length = SIZE;
sqList->listSize = SIZE;
}

void printSqlist(SqList *sqList) {
assert(sqList != NULL);
long i = 0;
for(; i < sqList->length; i++) {
printf("%d, ", sqList->elems[i]);
}
printf("打印完成\n");
}

void copyDiff(SqList *sqList) {
struct timeval startTime, endTime;

SqList *temp = (SqList *) malloc(sizeof(SqList));
temp->elems = (int *) malloc(sizeof(int) * SIZE);
temp->length = SIZE;
temp->listSize = SIZE;

long i = 0;
for(; i < 5; i++) {
gettimeofday(&startTime, NULL);
copyByFor(sqList, temp, sqList->length);
gettimeofday(&endTime, NULL);
printf("for循环拷贝数组%d个元素耗时%ld ms\n", SIZE, (endTime.tv_sec * 1000  + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000));

gettimeofday(&startTime, NULL);
copyByBit(sqList, temp, sqList->length);
gettimeofday(&endTime, NULL);
printf("字节拷贝数组%d个元素耗时%ld ms\n", SIZE, (endTime.tv_sec * 1000  + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000));

gettimeofday(&startTime, NULL);
copyByMem(sqList, temp, sqList->length);
gettimeofday(&endTime, NULL);
printf("memcpy拷贝数组%d个元素耗时%ld ms\n", SIZE, (endTime.tv_sec * 1000  + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000));
puts("");
}

}

void copyByFor(SqList *star, SqList *end, int len) {
assert(star != NULL && end != NULL && len > 0);
int *from = star->elems;
int *to = end->elems;
long i = 0;
for( ; i < len; i++ ) {
to[i] = from[i];
}
}

void copyByBit(SqList *star, SqList *end, int len) {
assert(star != NULL && end != NULL && len > 0);
char *from, *to;
from = (char *) star->elems;
to = (char *) end->elems;
long i = 0;
len = len * sizeof(int);
for(; i < len ; i++) {
*to++ = *from++;
}
}

void copyByMem(SqList *star, SqList *end, int len) {
assert(star != NULL && end != NULL && len > 0);
memcpy(end->elems, star->elems, len * sizeof(int));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: