用 C 更快地读取文件

2024-05-12

嗯,我想知道是否有一种比使用 fscanf() 更快地读取文件的方法

例如假设我有这个文本

4

55 k

52 o

24 l

523 i

首先,我想读取第一个数字,它给出了接下来的行数。

令这个数称为N。

N 之后,我想读取 N 行,其中有一个整数和一个字符。 和fscanf会是这样的

fscanf(fin,"%d %c",&a,&c);

您几乎不进行任何处理,因此瓶颈可能是文件系统吞吐量。但是,您应该先测量一下是否确实如此。如果您不想使用分析器,您可以只测量应用程序的运行时间。输入文件的大小除以运行时间可用于检查是否已达到文件系统吞吐量限制。

那么,如果您远离上述限制,您可能需要优化读取文件的方式。使用更大的块读取它可能会更好fread()然后处理存储在内存中的缓冲区sscanf().

您还可以自己解析缓冲区,这会比*scanf().

[edit]

特别是对于德拉科沙:

$ time ./main1
Good entries: 10000000

real    0m3.732s
user    0m3.531s
sys 0m0.109s
$ time ./main2
Good entries: 10000000

real    0m0.605s
user    0m0.496s
sys 0m0.094s

因此,优化版本的速度约为 127MB/s,这可能是我的文件系统的瓶颈,或者可能是操作系统将文件缓存在 RAM 中。原始版本约为 20MB/s。

使用 80MB 文件进行测试:

10000000

1234 a

1234 a
...

main1.c

#include <stdio.h>

int ok = 0;
void processEntry(int a, char c) {
    if (a == 1234 && c == 'a') {
        ++ok;
    }
}

int main(int argc, char **argv) {
    FILE *f = fopen("data.txt", "r");
    int total = 0;
    int a;
    char c;
    int i = 0;

    fscanf(f, "%d", &total);
    for (i = 0; i < total; ++i) {
        if (2 != fscanf(f, "%d %c", &a, &c)) {
            fclose(f);
            return 1;
        }
        processEntry(a, c);
    }
    fclose(f);
    printf("Good entries: %d\n", ok);
    return (ok == total) ? 0 : 1;
}

main2.c

#include <stdio.h>
#include <stdlib.h>

int ok = 0;
void processEntry(int a, char c) {
    if (a == 1234 && c == 'a') {
        ++ok;
    }
}

int main(int argc, char **argv) {
    FILE *f = fopen("data.txt", "r");
    int total = 0;
    int a;
    char c;
    int i = 0;
    char *numberPtr = NULL;
    char buf[2048];
    size_t toProcess = sizeof(buf);
    int state = 0;
    int fileLength, lengthLeft;

    fseek(f, 0, SEEK_END);
    fileLength = ftell(f);
    fseek(f, 0, SEEK_SET);

    fscanf(f, "%d", &total);  // read the first line

    lengthLeft = fileLength - ftell(f);

    // read other lines using FSM
    do {
        if (lengthLeft < sizeof(buf)) {
            fread(buf, lengthLeft, 1, f);
            toProcess = lengthLeft;
        } else {
            fread(buf, sizeof(buf), 1, f);
            toProcess = sizeof(buf);
        }
        lengthLeft -= toProcess;
        for (i = 0; i < toProcess; ++i) {
            switch (state) {
                case 0:
                    if (isdigit(buf[i])) {
                        state = 1;
                        a = buf[i] - '0';
                    }
                    break;
                case 1:
                    if (isdigit(buf[i])) {
                        a = a * 10 + buf[i] - '0';
                    } else {
                        state = 2;
                    }
                    break;
                case 2:
                    if (isalpha(buf[i])) {
                        state = 0;
                        c = buf[i];
                        processEntry(a, c);
                    }
                    break;
            }
        }
    } while (toProcess == sizeof(buf));

    fclose(f);
    printf("Good entries: %d\n", ok);
    return (ok == total) ? 0 : 1;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用 C 更快地读取文件 的相关文章

  • boost::interprocess 准备好迎接黄金时间了吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在开发一个由内存映射文件支持的线
  • .NET Windows 服务中调用 C# 的 wait 的 I/O 回调是否可以不阻塞?

    我知道在 ASP NET 中 当使用 wait 时工作线程会返回到池中 而 I O 发生在后台 这对于可扩展性非常有用 我的 Windows 服务是一个套接字服务器 它使用 Begin End 样式的异步套接字 I O 混合我的魔法 我知道
  • C++ - 模板专业化和部分专业化

    我一直在互联网和 stackoverflow 上寻找具体的答案 但我似乎找不到 我必须创建一个通用类 然后实现特定的功能 我的具体说明是 您需要使用模板表达式参数以及模板类专业化和部分专业化 我有一个模板类 template
  • 此插件导致 Outlook 启动缓慢

    我正在使用 C NET 4 5 开发 Outlook Addin 项目 但部署后 有时 Outlook 会禁用我的插件 并显示此消息 这个插件导致 Outlook 启动缓慢 我不知道我的插件出了什么问题 这只有很少的代码 并且ThisAdd
  • C++:获取注册表值仅给出第一个字符[重复]

    这个问题在这里已经有答案了 我试图从注册表中获取字符串值 但我只得到第一个字母 HKEY hKey char gamePath MAX PATH if RegOpenKeyEx HKEY CURRENT USER L Software Bl
  • 隐形打开的弹出窗口

    第二天就解决这个问题 要重现 请创建新的 WPF 应用程序 xaml
  • C# ConfigurationManager 从 app.config 检索错误的连接字符串

    我有一个简单的 WinForms 应用程序 它最终将成为一个游戏 现在 我正在研究它的数据访问层 但遇到了障碍 我创建了一个单独的项目 名为DataAccess在其中 我创建了一个本地 mdfSQL Server 数据库文件 我还创建了一个
  • 将语句插入 SQL Server 数据库

    最近几天我试图找到这个错误 但没有成功 我正在尝试在数据库中插入一个新行 一切都很顺利 没有错误 也没有程序崩溃 My INSERT声明如下 INSERT INTO Polozaj Znesek Uporabnik Cas Kupec Po
  • 当我尝试使用 AVX 功能时,Clang 生成错误

    我使用的是 Windows 10 使用 Clang 版本 5 最近安装 当我编译以下内容时 define AVX define AVX2 include
  • Type_traits *_v 变量模板实用程序顺序无法编译

    看过了这个答案 https stackoverflow com a 31763111 7151494 我试图想出一个变量模板从中获取代码的实用程序 template
  • 从 ef core 的子集合中删除一些项目

    我有一个父表和子表 其中父表与子表具有一对多关系 我想删除一些子项 并且希望父项的子集合反映该更改 如果我使用删除选定的子项RemoveRange 那么子集合不会更新 如果我使用Remove从子集合中删除子集合然后 显然 它不如使用效率高R
  • 在 C# 中生成随机值

    如何使用以下命令生成随机 Int64 和 UInt64 值RandomC 中的类 这应该可以解决问题 这是一个扩展方法 因此您可以像调用普通方法一样调用它Next or NextDouble上的方法Random目的 public stati
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • C# - 命名空间内的类型声明

    在命名空间内而不是在类中声明类型的可能用途是什么 For ex namespace Test public delegate void Ispossible 这是有效的并且不会产生任何编译错误 但我无法想象为什么我们会以这种方式声明它而不是
  • 检索 Autofac 容器以解析服务

    在 C WindowForms 应用程序中 我启动一个 OWIN WebApp 它创建另一个类 Erp 的单例实例 public partial class Engine Form const string url http 8080 49
  • 获取大于某个数字的元素个数

    我正在尝试解决以下问题 数字被插入到容器中 每次插入数字时 我需要知道容器中有多少元素大于或等于当前插入的数字 我相信这两个操作都可以以对数复杂度完成 我的问题 C 库中有标准容器可以解决这个问题吗 我知道std multiset可以在对数
  • 无效的模板相关成员函数模板推导 - 认为我正在尝试使用 std::set

    我有一个继承自基类模板的类模板 基类模板有一个数据成员和一个成员函数模板 我想从我的超类中调用它 我知道为了消除对成员函数模板的调用的歧义 我必须使用template关键字 我必须明确引用this在超级班里 this gt base mem
  • 编译器什么时候内联函数?

    在 C 中 函数仅在显式声明时才内联inline 或在头文件中定义 或者编译器是否允许内联函数 因为他们认为合适 The inline关键字实际上只是告诉链接器 或告诉编译器告诉链接器 同一函数的多个相同定义不是错误 如果您想在标头中定义函
  • C# 中成员访问中的问号是什么意思?

    有人可以向我解释一下以下代码中会员访问中的问号是什么意思吗 它是标准 C 的一部分吗 尝试在 Xamarin Studio 中编译此文件时出现解析错误 this AnalyzerLoadFailed Invoke this new Anal
  • XmlDocument Save 使文件保持打开状态

    我有一个简单的 C 函数 可以创建一个基本的 XML 文件并保存 private void CreateXMlFile string Filename string Name string Company XmlDocument doc n

随机推荐

  • Rust 中如何将字符串转换为二进制字符串?

    我有一个字符串 我想将其转换为二进制字符串 let content request version to string request length to string request json 您可能指的是类型中字符串的二进制表示形式St
  • 获取计算机的MAC地址

    我想使用c 访问计算机的mac地址 我使用以下代码来访问 mac 地址 但此代码存在一些问题 Code 1 foreach NetworkInterface nic in NetworkInterface GetAllNetworkInte
  • 在 CollapsingToolbarLayout 中设置 minHeight 没有任何效果

    我目前使用 CollapsingToolbarLayout 遇到的主要问题是 无论我尝试什么 工具栏的 minHeight 属性都没有任何效果 我想要的结果是这样的 CollapsingToolbarLayout 具有一定的展开高度和一定的
  • 在 Tomcat 上部署 Java Web 项目,无需 WAR 或 EAR

    我有一个 Java Web 项目 Struts Spring 在我的本地主机上完美运行 我必须将其部署在我的网站上 但虚拟主机提供的 Tomcat Manager 界面显示 由于安全原因 它无法上传 WAR 文件 当联系技术支持时 我被告知
  • 我可以为CSS写一个循环吗

    我有一个场景 我得到像这样生成的 ID div class containerLength div div div div div div div div div 等等 有没有办法我可以编写一些CSS来通过循环来定位它们 也许像 new i
  • 在 UserClosing 和 this.close 上触发关闭事件

    我有一个表单 上面有一个 LogOutEvent 和一个表单关闭事件 这是代码 private void btnLogOut Click object sender EventArgs e DialogResult yesNo Messag
  • 仅在可能的情况下转换为 E164?

    我能否确定用户输入的电话号码是否可以安全地格式化为 E164 对于德国 这要求用户以本地区号开始输入 例如 123456可能是他所在城市的用户号码 但无法格式化为 E164 因为我们不知道他的本地区号 然后我想保持条目原样 相反 输入089
  • 从核心数据存储创建 .sqlite 文件?

    我在书籍和提供 sqlite 文件下载的网站上看到过教程 sqlite 文件用于核心数据 如何获取 sqlite 文件FROM应用程序或核心数据存储TO我的桌面 如果您要创建一个预填充的 sqlite 文件以与 Core Data 一起使用
  • Python 添加/更新任意深度的 dict 元素

    有一个像这样的字典 my pets Rudolf animal cat legs 4 达到低于同等水平的更清洁的方法是什么 my pets Rudolf legs front right injured True my pets Rudol
  • Webpack将js/css文件内容直接注入到index.html

    我有这样的代码
  • Meteor 抛出 throwIfSelectorIsNotId 异常

    运行某些代码时 Meteor 会抛出 throwIfSelectorIsNotId 异常 我有两个客户端运行相同的代码 当第二个客户端运行相同的代码时会引发异常 无法弄清楚这个异常的含义以及抛出的原因 希望有人能够解释一下 对于客户端上的某
  • WPF:在 DependencyProperty.UnsetValue 上触发

    在回答中这个问题 https stackoverflow com questions 2596847 wpf applying a trigger on binding failure作出以下声明 理论上 可能 触发 x Static De
  • H264 字节流到图像文件

    第一次来这里所以要温柔 我已经在给定的 H 264 字节流上工作了几个星期 一般注意事项 字节流不是来自文件 它是从外部源实时提供给我的 字节流使用 Android 的媒体编解码器进行编码 当将流写入扩展名为 H264的文件时 VLC能够正
  • 通过删除连续的重复项来减少字符串长度

    我有一个包含 2 个字段的 R 数据框 ID WORD 1 AAAAABBBBB 2 ABCAAABBBDDD 3 我想通过仅保留字母而不是重复中的重复项来简化具有重复字母的单词 e g AAAAABBBBB应该给我AB and ABCAA
  • 除了在 Unity3D 中使用“Assets/Gizmos”之外,如何拥有自定义脚本图标

    我知道这个问题可能被问过很多次了 但它经常被回答错误 我想要的是 Use a custom icon for specific components scripts in the Inspector e g Figure 2 and Fig
  • 如何使用 jackson 反序列化为 Kotlin 集合

    我想要的示例代码 data class D val a String val b Int val jsonStr a value1 b 1 a value2 b 2 what I need val listOfD List
  • 在 JavaScript 中计算不包括周末和节假日的天数

    我正在尝试编写一个代码 其中将计算总天数 不包括周末和自定义假期 我通过 stackoverflow 和 adobe 论坛进行搜索以找到解决方案 并提供了以下代码 如果公共假期恰逢工作日 周六至周三 则不计算在内 我的问题是 如果公共假期落
  • Pylance:“property”与“int”不兼容

    from typing extensions import Protocol class IFoo Protocol value int class Foo IFoo property def value self gt int retur
  • ASP.Net Web API:在读取/上传请求正文之前发送响应

    我的控制器上有一个操作 应该上传大型 500mb 2gb 文件 例如 HttpPost public void PostFile FromUri Guid uploadId 在正文内部 执行一些检查 例如 uploadId 是否存在 然后将
  • 用 C 更快地读取文件

    嗯 我想知道是否有一种比使用 fscanf 更快地读取文件的方法 例如假设我有这个文本 4 55 k 52 o 24 l 523 i 首先 我想读取第一个数字 它给出了接下来的行数 令这个数称为N N 之后 我想读取 N 行 其中有一个整数