惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
J
Java Code Geeks
雷峰网
雷峰网
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
V
Vulnerabilities – Threatpost
S
Securelist
The Hacker News
The Hacker News
The Register - Security
The Register - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
G
Google Developers Blog
Hugging Face - Blog
Hugging Face - Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
AI
AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Schneier on Security
Schneier on Security
N
Netflix TechBlog - Medium
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hacker News: Front Page
博客园 - 司徒正美
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Security Latest
Security Latest
Engineering at Meta
Engineering at Meta
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
U
Unit 42
V
V2EX
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
Recorded Future
Recorded Future
P
Privacy & Cybersecurity Law Blog
美团技术团队
小众软件
小众软件
F
Fortinet All Blogs

博客园 - Brendan

[转载]Manually configuring Microsoft Internet Information Services (IIS) IIS与TOMCAT协同工作---在IIS下运行JSP页面 AXIS部署错误解决方案集锦 使用System.Web.Mail发送Mail的错误解决方案 类的XML序列化(XML Serialization) [翻译]你可以赚钱,但你不能赚时间 Windows 2003 Server配置IIS服务器(ASP, ASP.NET)全功略 Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive 用MS SQL Server事件探查器来跟踪数据库的操作 反反编译工具——Deploy.NET C中获取当前时间的函数 替换函数(Substitution Function) 主定理(Master Theorem) Dynamic Programming之Longest Increasing Subsequence (LIS)问题 ADO.NET数据库连接模块 ASP.NET控件事件丢失的探究 SQLDMO For C#(翻译) 关联(Association)设计中的扇形陷阱(Fan Traps)和断层陷阱(Chasm Traps) 简单并发控制
Buffered I/O 与 Non-Buffered I/O性能差异的实例体验
Brendan · 2006-04-14 · via 博客园 - Brendan

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

未做buffer的程序代码:

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

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

 39
 40    if (position_rw_pntr(fd, midLines) == -1)
 41    {
 42        perror("Position_rw_pntr Error");
 43        return EXIT_FAILURE;
 44    }

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

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

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

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

 83        }

 84    }

 85
 86    if (lineNum < num_lines)
 87    {
 88        rw_ptr = 0;
 89    }

 90    else
 91    {    
 92        if (lineNum % 2)
 93        {
 94            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines + 1% 2 - 1];
 95        }

 96        else
 97        {
 98            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines) % 2 - 1];
 99        }

100    }

101    
102    return 1;
103}

104
105char* get_next_line(int fd) 
106{
107    int n, i;
108    char byteChar;
109    char* buf;
110
111    if (lseek(fd, rw_ptr, SEEK_SET) == -1
112    {
113        return NULL;
114    }

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

126        else
127        {
128            buf[i] = byteChar;
129        }

130    }

131
132    return buf;
133}

134
135int get_next_char(int fd)
136{
137    char charBuf[1];
138    if (lseek(fd, rw_ptr, SEEK_SET) == -1
139    {
140        return EOF;
141    }

142    
143    rw_ptr++;
144    if (read(fd, charBuf, 1== 0
145    {
146        return EOF;
147    }

148    return charBuf[0];
149}

150

做了buffer的程序代码:

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

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

 43
 44    if (position_rw_pntr(fd, midLines) == -1)
 45    {
 46        perror("Position_rw_pntr Error");
 47        return EXIT_FAILURE;
 48    }

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

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

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

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

 87        }

 88    }

 89
 90    if (lineNum < num_lines)
 91    {
 92        rw_ptr = 0;
 93    }

 94    else
 95    {    
 96        if (lineNum % 2)
 97        {
 98            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines + 1% 2 - 1];
 99        }

100        else
101        {
102            rw_ptr = lineCount[(lineNum - num_lines) / 2 + (lineNum - num_lines) % 2 - 1];
103        }

104    }

105
106    return 1;
107}

108
109char* get_next_line(int fd) 
110{
111    int n, i;
112    char byteChar;
113    char* buf;
114
115    if (lseek(fd, rw_ptr, SEEK_SET) == -1
116    {
117        return NULL;
118    }

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

131        else
132        {
133            buf[i] = byteChar;
134        }

135    }

136
137    return buf;
138}

139
140int get_next_char(int fd)
141{
142    int n;
143    if (lseek(fd, rw_ptr, SEEK_SET) == -1
144    {
145        return EOF;
146    }

147
148    if (linePtr == 0)
149    {
150        if ((curBufSize = read(fd, lineBuf, INIT_BUFF_SIZE)) == 0)
151        {
152            return EOF;
153        }

154        linePtr = 0;
155    }

156    
157    if (linePtr < curBufSize)
158    {
159        rw_ptr++;
160        return lineBuf[linePtr++];
161    }

162    else
163    {
164        if ((curBufSize = read(fd, lineBuf, INC_BUFF_SIZE)) == 0)
165        {
166            return EOF;
167        }

168        else
169        {
170            rw_ptr++;
171            linePtr = 0;
172            return lineBuf[linePtr++];
173        }

174    }

175}

176
177

最后用了一个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,效果将更明显。