Buffered I/O 与 Non-Buffered I/O性能差异的实例体验

        帮同学作一个作业,写了两个程序,完成的功能类似LINUX中的head和tail命令,可以获取一个文件中间的几行。这两个程序实现的是同一个功能,但是一个用的是一个类似LIBC中的fgetc的函数到文件里一个一个字符地取;而第二个程序则是用了行缓存,通过INIT_LINE_BUFFER和INC_LINE_BUFFER来控制,缓存大小和扩展大小。程序旨在说明问题,如果代码上有什么丑陋的,请包涵。

未做buffer的程序代码:
  1 None.gif #include  < stdio.h >
  2 None.gif#include  < stdlib.h >
  3 None.gif#include  < sys / types.h >
  4 None.gif#include  < sys / stat.h >
  5 None.gif#include  < string .h >
  6 None.gif#include  < unistd.h >
  7 None.gif#include  < fcntl.h >
  8 None.gif
  9 None.gif #define  CHAR_BUFFER 1
 10 None.gif #define  BUFFER_SIZE 1024
 11 None.gif #define  LINE_BUFFER 128
 12 None.gif #define  MAX_FILE_LINE_NUM 1000000
 13 None.gif
 14 None.gif int  rw_ptr;   //  read-write pointer
 15 None.gif int  lineNum;   //  number of lines in the file
 16 None.gif
 17 None.gif int  position_rw_pntr( int  fd,  int  num_lines);
 18 None.gif char *  get_next_line( int  fd);
 19 None.gif int  get_next_char( int  fd);
 20 None.gif
 21 None.gif int  main( int  argc,  char   * argv[]) 
 22 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 23InBlock.gif    int midLines;
 24InBlock.gif    int i = 0;
 25InBlock.gif    char* lineString;
 26InBlock.gif    int succ;
 27InBlock.gif    int fd;
 28ExpandedSubBlockStart.gifContractedSubBlock.gif    if (argc != 3dot.gif{
 29InBlock.gif        printf("Usage: lab2 <lines> <file>\n");
 30InBlock.gif        return -1;
 31ExpandedSubBlockEnd.gif    }

 32InBlock.gif    
 33InBlock.gif    midLines = atoi(argv[1]);
 34InBlock.gif    if ((fd = open(argv[2], O_RDONLY)) == -1
 35ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 36InBlock.gif        perror("Open file error");
 37InBlock.gif        return EXIT_FAILURE;
 38ExpandedSubBlockEnd.gif    }

 39InBlock.gif
 40InBlock.gif    if (position_rw_pntr(fd, midLines) == -1)
 41ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 42InBlock.gif        perror("Position_rw_pntr Error");
 43InBlock.gif        return EXIT_FAILURE;
 44ExpandedSubBlockEnd.gif    }

 45InBlock.gif        
 46InBlock.gif    while (i != midLines && i != lineNum) 
 47ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 48InBlock.gif        lineString = get_next_line(fd);
 49InBlock.gif        printf("%s\n", lineString);
 50InBlock.gif        i++;
 51ExpandedSubBlockEnd.gif    }

 52InBlock.gif
 53InBlock.gif    free(lineString);
 54InBlock.gif    close(fd);
 55InBlock.gif    
 56InBlock.gif    return EXIT_SUCCESS;
 57ExpandedBlockEnd.gif}

 58 None.gif
 59 None.gif int  position_rw_pntr( int  fd,  int  num_lines) 
 60 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 61InBlock.gif    int start;
 62InBlock.gif    int i, n;
 63InBlock.gif    char buf[BUFFER_SIZE];
 64InBlock.gif    int* lineCount = (int *)malloc(MAX_FILE_LINE_NUM * sizeof(int));
 65InBlock.gif    int byteNum = 0;
 66InBlock.gif
 67InBlock.gif    if (lseek(fd, 0, SEEK_SET) == -1
 68ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 69InBlock.gif        return -1;
 70ExpandedSubBlockEnd.gif    }

 71InBlock.gif    
 72InBlock.gif    lineNum = 0;
 73InBlock.gif    lineCount[lineNum] = 0;
 74InBlock.gif    while ((n = read(fd, buf, BUFFER_SIZE)) != 0 ) 
 75ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 76InBlock.gif        for (i = 0; i < n; i++
 77ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 78InBlock.gif            byteNum++;
 79InBlock.gif            if (buf[i] == '\n'
 80ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 81InBlock.gif                lineCount[++lineNum] = byteNum;
 82ExpandedSubBlockEnd.gif            }

 83ExpandedSubBlockEnd.gif        }

 84ExpandedSubBlockEnd.gif    }

 85InBlock.gif
 86InBlock.gif    if (lineNum < num_lines)
 87ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 88InBlock.gif        rw_ptr = 0;
 89ExpandedSubBlockEnd.gif    }

 90InBlock.gif    else
 91ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{    
 92InBlock.gif        if (lineNum % 2)
 93ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 94InBlock.gif            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines + 1% 2 - 1];
 95ExpandedSubBlockEnd.gif        }

 96InBlock.gif        else
 97ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 98InBlock.gif            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines) % 2 - 1];
 99ExpandedSubBlockEnd.gif        }

100ExpandedSubBlockEnd.gif    }

101InBlock.gif    
102InBlock.gif    return 1;
103ExpandedBlockEnd.gif}

104 None.gif
105 None.gif char *  get_next_line( int  fd) 
106 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
107InBlock.gif    int n, i;
108InBlock.gif    char byteChar;
109InBlock.gif    char* buf;
110InBlock.gif
111InBlock.gif    if (lseek(fd, rw_ptr, SEEK_SET) == -1
112ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
113InBlock.gif        return NULL;
114ExpandedSubBlockEnd.gif    }

115InBlock.gif    
116InBlock.gif    buf = (char *)malloc(LINE_BUFFER * sizeof(char));
117InBlock.gif
118InBlock.gif    for (i = 0; i < LINE_BUFFER; i++
119ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
120InBlock.gif        byteChar = (char)get_next_char(fd);
121InBlock.gif        if (byteChar == EOF || byteChar == '\n')
122ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
123InBlock.gif            buf[i] = '\0';
124InBlock.gif            break;
125ExpandedSubBlockEnd.gif        }

126InBlock.gif        else
127ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
128InBlock.gif            buf[i] = byteChar;
129ExpandedSubBlockEnd.gif        }

130ExpandedSubBlockEnd.gif    }

131InBlock.gif
132InBlock.gif    return buf;
133ExpandedBlockEnd.gif}

134 None.gif
135 None.gif int  get_next_char( int  fd)
136 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
137InBlock.gif    char charBuf[1];
138InBlock.gif    if (lseek(fd, rw_ptr, SEEK_SET) == -1
139ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
140InBlock.gif        return EOF;
141ExpandedSubBlockEnd.gif    }

142InBlock.gif    
143InBlock.gif    rw_ptr++;
144InBlock.gif    if (read(fd, charBuf, 1== 0
145ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
146InBlock.gif        return EOF;
147ExpandedSubBlockEnd.gif    }

148InBlock.gif    return charBuf[0];
149ExpandedBlockEnd.gif}

150 None.gif


做了buffer的程序代码:
  1 None.gif #include  < stdio.h >
  2 None.gif#include  < stdlib.h >
  3 None.gif#include  < sys / types.h >
  4 None.gif#include  < sys / stat.h >
  5 None.gif#include  < string .h >
  6 None.gif#include  < unistd.h >
  7 None.gif#include  < fcntl.h >
  8 None.gif
  9 None.gif #define  BUFFER_SIZE 1024
 10 None.gif #define  INIT_BUFF_SIZE 64
 11 None.gif #define  INC_BUFF_SIZE 8
 12 None.gif #define  LINE_BUFFER 128
 13 None.gif #define  MAX_FILE_LINE_NUM 1000000
 14 None.gif
 15 None.gif int  rw_ptr;   //  read-write pointer
 16 None.gif int  lineNum;   //  number of lines in the file
 17 None.gif char  lineBuf[INIT_BUFF_SIZE];
 18 None.gif int  linePtr;
 19 None.gif int  curBufSize;
 20 None.gif
 21 None.gif int  position_rw_pntr( int  fd,  int  num_lines);
 22 None.gif char *  get_next_line( int  fd);
 23 None.gif int  get_next_char( int  fd);
 24 None.gif
 25 None.gif int  main( int  argc,  char   * argv[]) 
 26 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 27InBlock.gif    int midLines;
 28InBlock.gif    int i = 0;
 29InBlock.gif    char* lineString;
 30InBlock.gif    int succ;
 31InBlock.gif    int fd;
 32ExpandedSubBlockStart.gifContractedSubBlock.gif    if (argc != 3dot.gif{
 33InBlock.gif        printf("Usage: lab2 <lines> <file>\n");
 34InBlock.gif        return -1;
 35ExpandedSubBlockEnd.gif    }

 36InBlock.gif
 37InBlock.gif    midLines = atoi(argv[1]);
 38InBlock.gif    if ((fd = open(argv[2], O_RDONLY)) == -1
 39ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 40InBlock.gif        perror("Open file error");
 41InBlock.gif        return EXIT_FAILURE;
 42ExpandedSubBlockEnd.gif    }

 43InBlock.gif
 44InBlock.gif    if (position_rw_pntr(fd, midLines) == -1)
 45ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 46InBlock.gif        perror("Position_rw_pntr Error");
 47InBlock.gif        return EXIT_FAILURE;
 48ExpandedSubBlockEnd.gif    }

 49InBlock.gif
 50InBlock.gif    while (i != midLines && i != lineNum) 
 51ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 52InBlock.gif        lineString = get_next_line(fd);
 53InBlock.gif        printf("%s\n", lineString);
 54InBlock.gif        i++;
 55ExpandedSubBlockEnd.gif    }

 56InBlock.gif
 57InBlock.gif    free(lineString);
 58InBlock.gif    close(fd);
 59InBlock.gif
 60InBlock.gif    return EXIT_SUCCESS;
 61ExpandedBlockEnd.gif}

 62 None.gif
 63 None.gif int  position_rw_pntr( int  fd,  int  num_lines) 
 64 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 65InBlock.gif    int start;
 66InBlock.gif    int i, n;
 67InBlock.gif    char buf[BUFFER_SIZE];
 68InBlock.gif    int* lineCount = (int *)malloc(MAX_FILE_LINE_NUM * sizeof(int));
 69InBlock.gif    int byteNum = 0;
 70InBlock.gif
 71InBlock.gif    if (lseek(fd, 0, SEEK_SET) == -1
 72ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 73InBlock.gif        return -1;
 74ExpandedSubBlockEnd.gif    }

 75InBlock.gif
 76InBlock.gif    lineNum = 0;
 77InBlock.gif    lineCount[lineNum] = 0;
 78InBlock.gif    while ((n = read(fd, buf, BUFFER_SIZE)) != 0 ) 
 79ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 80InBlock.gif        for (i = 0; i < n; i++
 81ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 82InBlock.gif            byteNum++;
 83InBlock.gif            if (buf[i] == '\n'
 84ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 85InBlock.gif                lineCount[++lineNum] = byteNum;
 86ExpandedSubBlockEnd.gif            }

 87ExpandedSubBlockEnd.gif        }

 88ExpandedSubBlockEnd.gif    }

 89InBlock.gif
 90InBlock.gif    if (lineNum < num_lines)
 91ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 92InBlock.gif        rw_ptr = 0;
 93ExpandedSubBlockEnd.gif    }

 94InBlock.gif    else
 95ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{    
 96InBlock.gif        if (lineNum % 2)
 97ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 98InBlock.gif            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines + 1% 2 - 1];
 99ExpandedSubBlockEnd.gif        }

100InBlock.gif        else
101ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
102InBlock.gif            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines) % 2 - 1];
103ExpandedSubBlockEnd.gif        }

104ExpandedSubBlockEnd.gif    }

105InBlock.gif
106InBlock.gif    return 1;
107ExpandedBlockEnd.gif}

108 None.gif
109 None.gif char *  get_next_line( int  fd) 
110 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
111InBlock.gif    int n, i;
112InBlock.gif    char byteChar;
113InBlock.gif    char* buf;
114InBlock.gif
115InBlock.gif    if (lseek(fd, rw_ptr, SEEK_SET) == -1
116ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
117InBlock.gif        return NULL;
118ExpandedSubBlockEnd.gif    }

119InBlock.gif
120InBlock.gif    linePtr = 0;
121InBlock.gif    buf = (char *)malloc(LINE_BUFFER * sizeof(char));
122InBlock.gif    
123InBlock.gif    for (i = 0; i < LINE_BUFFER; i++
124ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
125InBlock.gif        byteChar = (char)get_next_char(fd);
126InBlock.gif        if (byteChar == EOF || byteChar == '\n')
127ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
128InBlock.gif            buf[i] = '\0';
129InBlock.gif            break;
130ExpandedSubBlockEnd.gif        }

131InBlock.gif        else
132ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
133InBlock.gif            buf[i] = byteChar;
134ExpandedSubBlockEnd.gif        }

135ExpandedSubBlockEnd.gif    }

136InBlock.gif
137InBlock.gif    return buf;
138ExpandedBlockEnd.gif}

139 None.gif
140 None.gif int  get_next_char( int  fd)
141 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
142InBlock.gif    int n;
143InBlock.gif    if (lseek(fd, rw_ptr, SEEK_SET) == -1
144ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
145InBlock.gif        return EOF;
146ExpandedSubBlockEnd.gif    }

147InBlock.gif
148InBlock.gif    if (linePtr == 0)
149ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
150InBlock.gif        if ((curBufSize = read(fd, lineBuf, INIT_BUFF_SIZE)) == 0)
151ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
152InBlock.gif            return EOF;
153ExpandedSubBlockEnd.gif        }

154InBlock.gif        linePtr = 0;
155ExpandedSubBlockEnd.gif    }

156InBlock.gif    
157InBlock.gif    if (linePtr < curBufSize)
158ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
159InBlock.gif        rw_ptr++;
160InBlock.gif        return lineBuf[linePtr++];
161ExpandedSubBlockEnd.gif    }

162InBlock.gif    else
163ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
164InBlock.gif        if ((curBufSize = read(fd, lineBuf, INC_BUFF_SIZE)) == 0)
165ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
166InBlock.gif            return EOF;
167ExpandedSubBlockEnd.gif        }

168InBlock.gif        else
169ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
170InBlock.gif            rw_ptr++;
171InBlock.gif            linePtr = 0;
172InBlock.gif            return lineBuf[linePtr++];
173ExpandedSubBlockEnd.gif        }

174ExpandedSubBlockEnd.gif    }

175ExpandedBlockEnd.gif}

176 None.gif
177 None.gif

最后用了一个shell脚本来测试两个的运行时间,比较其优劣(其中的BigFile.txt是一个很大的文件):
# !/bin/bash

set `date`
echo start test part1 at $
4
../ part1 / lab2 . exe  300000  BigFile . txt  >  part1 . bt
set `date`
echo finish test part1 at $
4
set `date`
echo start test part2 at $
4
../ part2 / lab2 . exe  300000  BigFile . txt  >  part2 . bt
set `date`
echo finish test part2 at $
4

用个跑下来,前者要比后者慢一倍。可见buffer的好处。如果调高buffer的size,效果将更明显。

转载于:https://www.cnblogs.com/sjpisaboy/archive/2006/04/14/375599.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值