我们都知道,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下系统函数库 区别 (即带不带缓冲区的学习)的更多相关文章

  1. 如何在Linux下添加函数库

    如何为Linux增加库一. 静态库在Linux下的静态库是以.a为后缀的文件.1. 建静态库h1.c 源文件#include<stdio.h>void hello1(){printf(“t ...

  2. Linux下系统时间函数、DST等相关问题总结(转)

    Linux下系统时间函数.DST等相关问题总结 下面这个结构体存储了跟时区相关的位移量(offset)以及是否存在DST等信息,根据所在的时区信息,很容易找到系统时间与UTC时间之间的时区偏移,另外根 ...

  3. Linux下c函数dlopen实现加载动态库so文件代码举例

    dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了. ...

  4. 对于linux下system()函数的深度理解(整理)

    原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...

  5. 转:对于linux下system()函数的深度理解(整理)

    这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...

  6. [转帖]Linux下fork函数及pthread函数的总结

    Linux下fork函数及pthread函数的总结 https://blog.csdn.net/wangdd_199326/article/details/76180514 fork Linux多进程 ...

  7. (笔记)Linux下system()函数的深度理解(整理)

    注:从其它地方转的非常好的一篇文章,值得深究! 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数 ...

  8. 【C/C++】Linux下system()函数引发的错误

    http://my.oschina.net/renhc/blog/54582 [C/C++]Linux下system()函数引发的错误 恋恋美食  恋恋美食 发布时间: 2012/04/21 11:3 ...

  9. linux下sprintf_s函数的替代

    error code: ]; sprintf_s(buf, , "predicted position:(%3d, %3d)", predict_pt.x, predict_pt. ...

随机推荐

  1. JS的执行和加载(笔记)

    无论当前JS代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JS执行过程耗时越久,浏览器等待响应用户输入的时间就越长.当浏览器遇到内嵌的JS代码时会停止处理页面,先执行JS代 ...

  2. linux nginx服务 反向代理 负载均衡 nfs服务

    一.nginx服务 1.首先软件停用firewall #systemctl stop firewalld stop:本次停用 disable:开机停用 enable:开机启用 #ps aux | gr ...

  3. 【转】WPF的知识

    [-] 闲话WPF之二XAML概述 闲话WPF之五XAML中的类型转换 闲话WPF之十六WPF中的资源 2 闲话WPF之十九WPF中的传递事件 1 闲话WPF之二十WPF中的传递事件 2 闲话WPF之 ...

  4. 在Linode VPS上搭建最新版Transmission

    在Linode VPS上搭建最新版Transmission 2015-09-16 by Hansen 原文链接:http://www.hansendong.me/archives/124.html 以 ...

  5. Python——杂记

    python 最近出错总结: 1.而for..in ..中不要用else if  x in y:     print  else:     print2.def fibs(num): ...     ...

  6. mysql处理旧数据-使用模板以及临时表,不建议直接使用本表!!

    一 业务背景新版本中新建了一个项目的角色表,即每个项目都拥有几个角色,原来历史项目是没有角色的,这就要求使用脚本对表中的历史项目进行处理, 业务需求:每个项目都要有三个角色: 表 : pm_proje ...

  7. CodeForces 1096E: The Top Scorer

    一道经典组合数学+容斥题. 题目传送门:CF1096E. 题意简述: \(p\) 个人,每个人有得分 \(a_i\). 总得分 \(\sum a_i = s\). 第一个人得分 \(a_1 \ge r ...

  8. sru源码--language model

    import sys import os import argparse import time import random import math import numpy as np import ...

  9. 虚拟机使用主机ss代理

    环境Linux mint 设置好主机ss代理,并开启[允许来自局域网的链接] 在Linux虚拟机的system setting-network手动设置代理 地址全部填入刚刚的主机地址,端口号为主机ss ...

  10. shell脚本练习题->1

    猜随机数的大小 描述: 写一个猜数字脚本,当用户输入的数字和预设数字(随机生成一个0-100的数字)一样时,直接退出,否则让用户一直输入:并且提示用户输入的数字比预设数字大或者小 分析: 1:随机数字 ...