讀寫檔案速度測試

來源:互聯網
上載者:User
 

一. 檔案一次讀入速度

linux下讀檔案這東西最後都是要通過系統調用sys_read(fd,buf,count)來實現的,所以如果要提高速度,就是最簡單地調用sys_read的封裝,比如直接用read()或fread()。下面是我在linux下的幾個測試。

首先建立一個130M資料檔案 dd if=/dev/zero of=data bs=1024k count=130

[dd if=/dev/zero of=data bs=1024k count=130 轉換和拷貝檔案,從輸入if的源往of的目的地址拷貝,每個block1024k,一共拷貝130個。]

分別用fread,read和fgets一次讀入全部大小檔案所消耗時間對比,其中
size=130*1024*1024
char *buf=new char[size];

下面是測試結果(機器Intel(R) Pentium(R) 4 CPU 3.20GHz, Mem 1G):
1.fread(buf,size,1,fp)一次讀入
real    0m0.187s
user    0m0.000s
sys     0m0.180s

2.read(fdin,(void *)buf,size)一次讀入
real    0m0.187s
user    0m0.000s
sys     0m0.184s

3.多次fgets(buf,size,fp),每次1k
real    0m0.356s
user    0m0.136s
sys     0m0.220s

4.fgets(buf,size,fp)一次讀入
real    0m0.305s
user    0m0.072s
sys     0m0.232s

上面看到越簡單的函數(read()和fread()),速度越快,其他的輸入封裝函數只不過是為了方便滿足特殊需要,並不見得讀的速度會很快。對於3和 4,因為在sys_read()內部有對讀入大小的判斷和while迴圈,所以大檔案讀取也沒必要像3那樣分多次調用fgets()來讀檔案.

另外用mmap()記憶體映射來讀入檔案的時間如下:
real    0m0.231s
user    0m0.068s
sys     0m0.164s

也並沒有比直接read()快,網上找到一種解釋是對於需要頻繁讀寫操作的,mmap效率才會顯著提高。下面來類比頻繁讀寫操作。

二. 檔案頻繁讀寫速度測試

1. 這一個測試類比頻繁檔案讀寫操作,500M大小的資料檔案data.in,每次從中讀入1k個位元組對每個位元組做加1簡單計算,再寫到另一個檔案data.out中。
//mmapx1.c
#define size 1024*1024*500
#define LEN 1024
#include <stdio.h>
int main()
{
    FILE *fp1,*fp2;
    char *buf=new char[LEN];
    int i,j;
    fp1=fopen("data.in","rb");
    fp2=fopen("data.out","wb");
    for(j=0;j<1024*500;j++)
    {
        fread(buf,1024,1,fp1);
        for(i=0;i<LEN;i++)
            buf[i]++;
        fwrite(buf,LEN,1,fp2);
    }
    printf("ok!/n");
    fclose(fp1);
    fclose(fp2);
}
time 命令測試時間,每次結果都不一樣,機器負載有關。5次輸出的結果如下:
real 19.592s     18.517s     18.003s     20.470s     20.004s
usr 2.924s       2.964s       3.000s       2.812s       2.972s
sys 2.472s       2.360s       2.344s       2.652s       0.396s

2. 如果採用記憶體映射,將檔案data.in映射到儲存區,就避免的對檔案的頻繁讀寫操作,而全部轉變為I/O儲存讀寫。下面一個程式就是用mmap映射將檔案data.in中每個資料加1儲存到data.out中。
//mmapx2.c
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#define size 1024*1024*500
#define LEN 1024
int main()
{
    int fdin,fdout;
    struct stat statbuf;
    void *src,*dst;
    char *p;
    int i,j;
    fdin=open("data.in",O_RDONLY);
    fdout=open("data.out",O_RDWR|O_CREAT|O_TRUNC);

    if((src=mmap(0,size,PROT_READ,MAP_SHARED,fdin,0))==MAP_FAILED)
    {
        printf("src map error/n");
        return -1;
    }
    lseek(fdout,size-1,SEEK_SET);
    write(fdout,"/0",1);
   //因為data.out是空檔案,必須建立一個空洞讓其大小成為size來進行下面的mmap

    if((dst=mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,fdout,0))==MAP_FAILED)
    {
        printf("dest map error/n");
        return -1;
    }
        memcpy(dst,src,size);
        p=(char*)dst;
    for(i=0;i<size/LEN;i++)
    {
        for(j=0;j<LEN;j++)
            p[j]++;
        p+=LEN;
    }
    printf("ok/n");
    close(fdout);
    return 0;
}
time測試的5次已耗用時間如下:
real  9.603s      8.977s      9.416s      9.587s      9.322s
usr  2.764s      2.748s      2.784s      2.840s      2.787s
sys  1.516s      1.384s      1.384s      1.224s      1.276s

結論:上面可以看到,對於頻繁IO讀寫,採用mmap儲存映射可以有效提高效率(20s到9s)

3.mmap記憶體映射還有一個好處,就是直接在一個檔案內任意讀寫修改某個位元組,就像操作儲存區一樣,比如下面一段程式是實現對data.in中每個位元組資料加1的計算。

//mmapx3.c
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#define size 1024*1024*500
#define LEN 1024
int main()
{
    int fd;
    void *src;
    char *p;
    int i,j;
    fd=open("data.in",O_RDWR);
    if((src=mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED)
    {
        printf("src map error/n");
        return -1;
    }
    p=(char*)src;
    for(i=0;i<size/LEN;i++)
    {
        for(j=0;j<LEN;j++)
            p[j]++;
        p+=LEN;
    }
    printf("ok/n");
    close(fd);
}
time測試的5次的已耗用時間如下:
real 2.820s     2.828s     2.856s     2.818s     2.889s
usr 2.624s     2.624s     2.676s     2.648s     2.584s
sys 0.196s     0.196s     0.176s     0.172s     0.288s

上面對一個大檔案內的所有位元組各自改變加1,並儲存在原來的檔案中,採用mmap儲存映射的方法可以大大提高效率。對於頻繁地隨機改寫某個檔案內的某些部分位元組內容的情況來說,這是一個有效選擇。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.