Performance 如何以非常高效的方式比较已排序文件(文件大小>;1GB)中的所有行
假设输入文件为:Performance 如何以非常高效的方式比较已排序文件(文件大小>;1GB)中的所有行,performance,file,Performance,File,假设输入文件为: Hi my name NONE Hi my name is ABC Hi my name is ABC Hi my name is DEF Hi my name is DEF Hi my name is XYZ 我必须创建以下输出: Hi my name NONE 1 Hi my name is ABC 2 Hi my name is DEF 2 Hi my name is XYZ 1 单行中的字数可以从2到10不等。文件大小将超过1GB 如何在尽可能短的时间内获得所需的输
Hi my name NONE
Hi my name is ABC
Hi my name is ABC
Hi my name is DEF
Hi my name is DEF
Hi my name is XYZ
我必须创建以下输出:
Hi my name NONE 1
Hi my name is ABC 2
Hi my name is DEF 2
Hi my name is XYZ 1
单行中的字数可以从2到10不等。文件大小将超过1GB
如何在尽可能短的时间内获得所需的输出。我现在的实现使用C++程序从文件中读取一行,然后与下一行进行比较。此实现的运行时间始终为O(n),其中n是文件中的字符数
为了提高运行时间,下一个选项是使用mmap。但在实施它之前,我只是想确认是否有更快的方法来实现它?使用任何其他语言/脚本?在大多数情况下,此操作将完全受I/O限制。(特别是使用设计良好的C++) 考虑到这一点,您可能需要关心的唯一瓶颈是磁盘 我想你会发现这是相关的: Ben Collins给出了一个非常好的答案,将mmap与标准读/写进行比较
uniq -c filename | perl -lane 'print "@F[1..$#F] $F[0]"'
perl步骤只是获取uniq的输出(看起来像“2 Hi我的名字是ABC”),并将其重新排序为“Hi我的名字是ABC 2”。你可以使用不同的语言,或者完全不使用
至于你关于运行时的问题,big-O似乎放错了地方;当然不可能在不到O(n)的时间内扫描整个文件mmap
和strchr
似乎是恒定因子加速的可能性,但基于stdio的方法可能足够好,除非你的stdio很差劲
这一点可以说明问题。它使用
fgets
,strcmp
,以及一些变量来完成一项非常简单的工作。好的,您正在比较的两个时间尺度实际上并不相关。第一个是算法复杂度,用O表示法表示。然而,这与读取文件的复杂性无关
假设在理想情况下,您的所有数据都在内存中,您必须使用算法查找重复数据-根据您的数据的组织方式(例如,简单列表、哈希映射等),您可以查找重复数据。如果您有一个完美的哈希(仅用于检测项目),您可以使用O(n^2)、O(n)甚至O(1)
从文件或映射到内存的读取根本与“大OH”符号无关,所以根本不考虑复杂性计算。您只需选择一个测量时间更短的文件即可。
单个文件中的字数可以从2到10不等。文件大小将超过1GB
。。。所以我们处理的是平均长度超过1亿个字母的单词?我认为OP的意思是每行2到10个单词。1。文件分类了吗?从你描述的方法来看,我想是这样的。2.这是家庭作业吗?如果是这样,你应该给它贴上这样的标签。如果没有,您有什么原因不能使用uniq?抱歉。我做了以下更改a)单行中的单词数,从2到10,以及b)更正了I/p数据否,这不是家庭作业。这是我在项目中面临的性能问题。规则C++程序花费太长时间来生成所需的O/P。i/p文件是上一个处理步骤的o/p之一。确定。我刚刚启动了uniq命令。让我看看它的性能如何。谢谢你的建议。亲爱的霍布斯,它工作得非常快。对于665MB的文件,只需要35秒。什么是魔法?@PiyushKansal没有秘密。uniq只是使用fgets
逐行读取文件,并使用strcmp
将该行与前一行进行比较。如果它们相同,则递增一个计数器。如果它们不同,它会将前一行与计数一起打印。它使用指针交换来交换“当前行”和“上一行”以避免复制字符串。我现在得到了它,所以关键是指针交换!!谢谢你的解释。事实上,在某些系统上,它会严重影响内存管理,从而导致垃圾收集。。。