apue file io 效率 练习

标准IO和系统调用的效率在apue书里面介绍的很清楚了,下面测试一下。

 第一步

   首先建立以个100M文件

  代码如下

    

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <fcntl.h>
 4 #include <string.h>
 5 #include <sys/stat.h>
 6 int main(int argc, char const *argv[])
 7 {
 8     if (argc != 3) {
 9         fprintf(stderr, "Usage:%s  <write content>  <filename>\n", argv[0]);
10         exit(EXIT_FAILURE);
11     }
12        char  *w = (char *)argv[1];
13       char  *filename = (char *)argv[2];
14       int  fd;
15       int n;
16       fd = open(filename, O_CREAT|O_RDWR);
17       if (fd < 0)
18           perror("open file error");
19        struct stat statbuf;
20       fstat(fd, &statbuf);
21      int filesize;
22      filesize = statbuf.st_size/1024/1024;
23      printf("%d  k\n", filesize);
24      n = strlen(w);
25      while (filesize <= 100) {
26           if (write(fd, w, n) != n)
27              perror("write error");
28          fstat(fd, &statbuf);
29          filesize = statbuf.st_size/1024/1024;
30 
31      }
32       exit(0);
33      
34 }

生成 100M左右的文件

./bigfile abcd123456789  bigfile.log

第二步 编写标准IO读写代码

    

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 int main(int argc, char const *argv[])
 5 {
 6   
 7     int size = atoi(argv[1]); 
 8       char buf[size];
 9      while (fgets(buf,size, stdin) != NULL) {
10            if (fputs(buf, stdout) == EOF)
11               perror("output error");
12       }  
13       exit(0);
14      
15 }

  gcc stand.c -o stand

 

第三步,编写系统调用读写

 

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <fcntl.h>
 5 
 6 int main(int argc, char const *argv[])
 7 {
 8  
 9       int size = atoi(argv[1]); 
10       char ch[size];
11      int n;
12      int fd;
13      //fd = open("bigfile.log", O_RDWR);
14      while ((n = read(STDIN_FILENO, &ch, size)) > 0)  {
15          if (write(STDOUT_FILENO, &ch, n) != n)
16              perror("write error");
17      }
18       exit(0);
19      
20 }

 gcc  systemwrite.c -o systemwrite

 

第四步 在不同的bufsize  copy 100 文件

 4-1 系统调用

[root@MiWiFi-R3-srv apuetest]# time ./systemwrite 512  < bigfile.log  > log.log

real    0m8.111s
user    0m0.075s
sys     0m3.891s

[root@MiWiFi-R3-srv apuetest]# time ./systemwrite 1024  < bigfile.log  > log.log

real    0m5.554s
user    0m0.049s
sys     0m2.500s

  [root@MiWiFi-R3-srv apuetest]# time ./systemwrite 4096  < bigfile.log  > log.log

real    0m3.122s
user    0m0.002s
sys     0m1.267s

[root@MiWiFi-R3-srv apuetest]# time ./standio 8192  < bigfile.log  > log.log    
real    0m2.354s
user    0m0.002s
sys     0m1.059s



[root@MiWiFi-R3-srv apuetest]# time ./standio 16384  < bigfile.log  > log.log   
real    0m0.953s
user    0m0.002s
sys     0m0.490s
[root@MiWiFi-R3-srv apuetest]# time ./standio 32768  < bigfile.log  > log.log

real    0m1.262s
user    0m0.003s
sys     0m0.810s
[root@MiWiFi-R3-srv apuetest]# time ./standio 65536  < bigfile.log  > log.log

real    0m1.184s
user    0m0.002s
sys     0m0.727s
[root@MiWiFi-R3-srv apuetest]# time ./standio 131072  < bigfile.log  > log.log

real    0m1.066s
user    0m0.002s
sys     0m0.579s
[root@MiWiFi-R3-srv apuetest]# time ./standio 524288  < bigfile.log  > log.log

real    0m1.146s
user    0m0.004s
sys     0m0.745s
[root@MiWiFi-R3-srv apuetest]# time ./standio 5242880  < bigfile.log  > log.log

real    0m1.134s
user    0m0.000s
sys     0m0.688s

可以看到bufsize 小,和 太大都会增加执行时间。

4-2  标准IO 的读写

  

 [root@MiWiFi-R3-srv apuetest]# time ./fstandio 512  < bigfile.log  > log1.log

real    0m7.325s
user    0m0.255s
sys     0m4.629s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 1024  < bigfile.log  > log1.log

real    0m2.912s
user    0m0.101s
sys     0m1.514s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 4096  < bigfile.log  > log1.log

real    0m3.020s
user    0m0.143s
sys     0m1.570s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 8192  < bigfile.log  > log1.log

real    0m2.946s
user    0m0.111s
sys     0m1.449s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 16384  < bigfile.log  > log1.log

real    0m2.001s
user    0m0.069s
sys     0m1.179s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 32768  < bigfile.log  > log1.log

real    0m1.566s
user    0m0.083s
sys     0m0.894s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 65536  < bigfile.log  > log1.log

real    0m1.362s
user    0m0.168s
sys     0m0.794s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 131072  < bigfile.log  > log1.log

real    0m1.237s
user    0m0.224s
sys     0m0.663s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 524288 < bigfile.log  > log1.log
real    0m1.172s
user    0m0.297s
sys     0m0.662s
[root@MiWiFi-R3-srv apuetest]# time ./fstandio 5242880 < bigfile.log  > log1.log

real    0m1.030s
user    0m0.366s
sys     0m0.507s
 

标准IO在bufsize 不同时,执行时间也相差不小。从系统调用的时间来看,bufseize越大系统调用时间就越快。

到底bufsize 多大会影响到系统调用的时间呢。

从上面的数据还是不能看出来。

能得出的结论是bufsize 确确实实在影响到了系统调用。

在允许的条件下,减少系统调用。

apue 上的结论是标准IO的有点是无需考虑缓冲以及最佳I/O长度的选择,系统调用时间几乎相同,上面的标准IO读写结果来看,系统时间在变化。

 

在看看标准io 但字节读写的效率

 

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 int main(int argc, char const *argv[])
 5 {
 6       int c;
 7       while ((c = getc(stdin)) != EOF)
 8          if (putc(c, stdout) == EOF)
 9              perror("output error");     
10      
11       exit(0);
12      
13 }

 

 

 gcc  fgetc.c -o fgetc

[root@MiWiFi-R3-srv apuetest]# time  ./fgetc < bigfile.log > logfgetc.log

real    0m7.272s
user    0m1.948s
sys     0m3.656s

系统调用时间和fgets还是不一样的。和apue 上说的不一样。
原因不太清楚,有时间看看glbc 的源码吧。

 

posted @ 2017-12-21 23:14  蜗牛码  阅读(233)  评论(0编辑  收藏  举报