fscanf和sscanf的速度

fscanf和sscanf的速度,c,scanf,C,Scanf,对于C作业,我应该将一个大文本文件中的单词分解,然后逐个处理。基本上,单词是字母表的任何线性序列。因为,这将是我的程序的瓶颈,我想让这个过程尽可能快 我的想法是使用扫描函数格式说明符([a-zA-z])将文件中的单词扫描到字符串缓冲区。如果缓冲区已满,我将检查文件中是否有更多的字母(基于文件指针所在的位置)。如果有,则增加缓冲区大小并继续将更多字母复制到缓冲区中,直到找到非字母 问题在于我是使用fscanf还是sscanf(将整个文件复制到字符串中)。一个比另一个快还是有更好的替代方案来代替我的

对于C作业,我应该将一个大文本文件中的单词分解,然后逐个处理。基本上,单词是字母表的任何线性序列。因为,这将是我的程序的瓶颈,我想让这个过程尽可能快

我的想法是使用扫描函数格式说明符([a-zA-z])将文件中的单词扫描到字符串缓冲区。如果缓冲区已满,我将检查文件中是否有更多的字母(基于文件指针所在的位置)。如果有,则增加缓冲区大小并继续将更多字母复制到缓冲区中,直到找到非字母


问题在于我是使用fscanf还是sscanf(将整个文件复制到字符串中)。一个比另一个快还是有更好的替代方案来代替我的想法?

你的问题几乎偏离主题,因为它需要基于观点的答案

要知道一种方法与另一种方法相比的速度有多快,唯一的方法是尝试这两种方法,并测量生成的可执行文件在真实数据上的性能

如今,普通电脑的计算能力非常强大,因此需要一个非常大的文件来衡量实际的性能差异

所以,继续实施你的想法吧。您似乎已经很好地理解了潜在的性能瓶颈,将这些想法转化为实际的C代码。为这个问题提供两个不同但正确的程序,并进行性能分析,应该会得到a+。作为雇主,我在测试中重视这种方法

PS:IMHO大部分时间都花在从文件系统获取数据上。如果文件大于可用内存,这应该是您的瓶颈。如果文件可以放入操作系统文件系统缓存中,那么后续的基准测试应该会比第一个测试提供更好的性能


如果允许您编写特定于系统的代码,请尝试使用
mmap
和simple
进行循环,通过mmaap
char
数组上的查找表进行显式测试。

您的问题几乎脱离主题,因为它需要基于意见的答案

要知道一种方法与另一种方法相比的速度有多快,唯一的方法是尝试这两种方法,并测量生成的可执行文件在真实数据上的性能

如今,普通电脑的计算能力非常强大,因此需要一个非常大的文件来衡量实际的性能差异

所以,继续实施你的想法吧。您似乎已经很好地理解了潜在的性能瓶颈,将这些想法转化为实际的C代码。为这个问题提供两个不同但正确的程序,并进行性能分析,应该会得到a+。作为雇主,我在测试中重视这种方法

PS:IMHO大部分时间都花在从文件系统获取数据上。如果文件大于可用内存,这应该是您的瓶颈。如果文件可以放入操作系统文件系统缓存中,那么后续的基准测试应该会比第一个测试提供更好的性能


如果允许您编写特定于系统的代码,请尝试使用
mmap
和simple
通过mmaap
char
数组上的查找表进行显式测试。

正如Heto在评论中指出的,这里的主要瓶颈可能是从磁盘读取文件,不是您决定使用的任何
scanf
功能变量

如果你真的想加速你的应用程序,你应该尝试建立一个管道。在描述应用程序时,您基本上分为两个阶段:将文件读入缓冲区,以及从缓冲区解析单词

如果您决定将整个文件读入一个字符串,然后在字符串上使用
sscanf
,则该活动可能是这样的:

reading: ████████████████
parsing:                 ████████████████
如果直接在文件上使用
fscanf
,您会得到一些不同的结果,因为您经常在读取和解析之间切换:

reading: █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
parsing:  █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
在这两种情况下,您最终花费的时间大致相同

但是,如果您可以异步执行文件i/o,那么您可以将等待来自磁盘的数据的时间与用于计算的时间重叠。理想情况下,你会得到这样的结果:

reading: ████████████████
parsing:  ████████████████
我的图表可能没有那么准确(我们已经指出解析应该比i/o花费更少的时间,所以两个条实际上不应该是相同的长度),但是您应该了解一下大致的想法。如果您可以设置一个管道,从处理中异步读取数据,那么通过重叠通信(从磁盘读取)和计算(解析),您可以获得很大的加速

您可以使用,或者只使用两个线程(其中一个从文件读取,另一个进行解析)执行简单的生产者/消费者设置,来实现这样的异步管道


老实说,除非你正在处理大量的文本文件,否则你很可能根本无法衡量你可能选择的任何一种方法在速度上的差异

这种流水线方法在执行计算密集型操作(不仅仅是扫描字符)时更适用,并且通信延迟更高(比如数据通过网络而不是从本地磁盘传输时)。然而,探索不同的选择仍然是一项很好的工作。毕竟,这项任务是人为设计的,重点是学习一些有用的东西,你以后可能会在实际项目中使用,对吗


另一方面,使用任何
scanf
可能比仅在缓冲区上循环提取字符串要慢。这是因为,使用任何
scanf
函数,代码首先需要解析格式字符串以确定您要查找的内容,然后实际解析输入。有时编译器可以做得很聪明