文件io详解

io分为缓冲io和无缓冲io,缓冲io是将数据放入用户进程空间的缓冲区,通过数据读取函数scanf等在缓冲区读取函数,printf甚至要达到固定的缓冲条件才能输出,如换行符、缓冲区大小1024、fflush这些,当然这里不介绍这些,无缓冲io则进程空间没有缓冲,只存在系统的内核缓冲区,现在我们进行一下缓冲io的读取速度对比

样例

#include <stdio.h>
#include <chrono>
#include <iostream>
#include <unistd.h>

const int MX = 100000000;

int main()
{
    char c;
    char *buf;
    buf = (char *)malloc(sizeof(char) * 9000);
    for (int i = 1; i <= 8192; i <<= 1)
    {
        int k = MX % i == 0 ? 0 : 1;
        auto start = std::chrono::system_clock::now();
        for(int j = 0; j < MX / i + k; ++j)
        {
            // printf("f");
            read(STDIN_FILENO, buf, i);
            // scanf("%c", &c);
        }
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

./a.out < data 运行时间对比

1:53980
2:27307
4:13865
8:6898
16:3549
32:1749
64:949
128:512
256:262
512:158
1024:91
2048:63
4096:49
8192:50

可发现随着缓冲区的增大速度逐渐变快,缓冲小的时候到缓冲区来回切换较多,就比如车子可以拉十块砖但只拉了一块砖,走了十趟,到了4096为巅峰,至于为什么是4096是巅峰我猜测是因为内存分页的缘故,我们的系统一般都是按4kb进行内存分页的,所以4096相当于卡车装的总数

现我们将有内核缓冲读取改为无内核缓冲读取测试

添加代码

void setnonblocking(int fd)
{
    int flags = fcntl(fd, F_GETFL, 0);
    flags |= O_NONBLOCK;
    if(fcntl(fd, F_SETFL, flags) < 0)
        perror("fcntl error");
}

setnonblocking(STDIN_FILENO);

./a.out < data

1:52624
2:27435
4:14176
8:7501
16:3943
32:1963
64:1072
128:611
256:378
512:213
1024:160
2048:84
4096:64
8192:62

从数据上看速度有些变慢,因为他要跑到内核缓冲区读取数据,路程变远了,所以造成了速度变慢了,但他不会造成阻塞,用它在网络io中使用些微的耗时增加就远不如网络阻塞的耗时增加,不过那时又会造成缓冲区满等问题,这里就不细说了

本文到此结束,有问题欢迎指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值