1. 程式人生 > >C語言檔案操作標準庫函式與Linux系統函式效率比較

C語言檔案操作標準庫函式與Linux系統函式效率比較

我們都知道,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就要差一點了,所以選擇一個合適的緩衝區尤為重要。