1. 程式人生 > >標準c庫函數與Linux下系統函數庫 區別 (即帶不帶緩沖區的學習)

標準c庫函數與Linux下系統函數庫 區別 (即帶不帶緩沖區的學習)

實現 使用 調用 pre 庫函數 緩沖區 覆蓋 發現 num

我們都知道,C語言在UNIX/Linux系統下有一套系統調用(系統函數),比如文件操作open()、close()、write()、read()等,而標準C語言的庫函數中也有一套對文件的操作函數fopen()、fclose()、fwrite()、fread()等.。那麽同樣是對文件的操作函數,標C與UC有什麽區別呢?是標C效率高還是UC效率高呢?今天就讓我們來一探究竟。

程序作用:將0~999999這1000000個整型數據寫入文件。

1、標準C實現大量數據寫入文件:

/*文件名test1.c*/
#include<stdio.h>
#include<stdlib.h>

#define MAX 1000000

int main (void)
{
    FILE * fp = fopen("test1.txt","w");
    if(fp == NULL){
        perror("fopen test1.txt");
        exit(EXIT_FAILURE);
    }

    int i;
    for(i = 0; i < MAX; i++){
        fwrite(&i, sizeof(int), 1, fp);/*我們采用fwrite一個一個寫入文件*/
    }

    fclose(fp);
    return 0;
}
/*gcc -o test1 test1.c編譯*/

寫入文件的效率測試結果:

技術分享圖片

2、Linux系統函數實現大量數據寫入文件:

/*文件名test2.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>

#define MAX 1000000

int main (void)
{
    int fd = open("test2.txt",O_RDWR|O_TRUNC|O_CREAT,0666);
    /*O_RDWR可讀可寫,O_CREAT沒有則新建,O_TRUNC覆蓋寫入(原有內容小清空),O_APPEND追加寫入(原有內容不清空)*/
    if(fd == -1){
        perror("open test2.txt");
        exit(EXIT_FAILURE);
    }

    int i;
    for(i = 0; i < MAX; i++){
        write(fd, &i, sizeof(int));
    }
    close(fd);
    return 0;
}
/*gcc -o test2 test2.c編譯*/

寫入效率測試結果:

技術分享圖片

我們發現系統函數的使用並沒有使程序運行速率(寫入速率)變快而是變慢了幾十倍,而且在測試中,我們可以看見增加的時間基本都是在sys(系統層面)中增加的。這是因為,系統函數在用戶層沒有緩沖區,在內核層有緩沖區,但是緩沖區很小,所以大量數據在寫入文件時,頻繁刷新緩沖區降低了寫入速率。所以系統函數(如write)需要加自定義緩沖區以提高速率,而標準C函數(如fwrite)不用自己設置緩沖區,如果系統函數用自定義緩沖區其效率比標C要好,不定義緩沖區則效率很低,但是緩沖區大小要合適,否則物極必反(即使有緩沖區,從緩沖區向文件中寫也是一個一個寫入的)。

3、Linux系統函數實現大量數據寫入文件修改:

/*文件名test3.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>

#define MAX 1000000
#define BUF_SIZE 500
/*緩沖區大小,合適為宜,多少為合適需要自己測試,但是不同大小的緩沖區影響肯定是不同的*/
int main (void)
{
    int fd = open("test3.txt",O_RDWR|O_TRUNC|O_CREAT,0666);
    if(fd == -1){
        perror("open test3.txt");
        exit(EXIT_FAILURE);
    }

    int i;
    int buffer[BUF_SIZE] = {0};
    for(i = 0; i < MAX; i++){
        buffer[i%BUF_SIZE] = i;
        if(i%BUF_SIZE == BUF_SIZE-1)
            write(fd, buffer, sizeof(buffer));/*當緩沖區寫滿時向文件中寫一次(刷新一次緩沖區)*/
    }

    close(fd);
    return 0;
}
/*gcc -o test3 test3.c編譯*/

寫入效率測試結果:

技術分享圖片

加入自定義緩沖區後的測試發現,其效率比不加自定緩沖區要快100多倍,比標C寫入速率也要快好幾倍。如果緩沖區大小合適,其效率會提升更大。那麽當我們將BUF_SZIE改為更大的值(BUF_SZIE=50000),重新編譯之後,測試結果如下:

技術分享圖片

該效率由提高了,所以選擇一個合適的緩沖區尤為重要。

標準c庫函數與Linux下系統函數庫 區別 (即帶不帶緩沖區的學習)