性能-Python与C#/C++/逐字符读取
所以我有这些巨大的XML文件(我的意思是1.5GB+),它们没有CRLF。我正在尝试运行一个类似于diff的程序来查找这些文件之间的差异 因为我还没有找到一个不会因为内存耗尽而爆炸的diff程序,所以我决定最好的办法是在关闭标记后添加CRLFs 我编写了一个python脚本来逐字符读取字符,并在“>”之后添加新行。问题是我在单核PC上运行这个程序大约是1995年,或者是一些荒谬的事情,当我同时进行转换时,它的处理速度只有20MB/小时 如果用C#/C/C++编写此代码,会有什么好处吗?如果没有,是否有人知道将逐字节运行的diff程序?谢谢性能-Python与C#/C++/逐字符读取,c#,python,performance,character,C#,Python,Performance,Character,所以我有这些巨大的XML文件(我的意思是1.5GB+),它们没有CRLF。我正在尝试运行一个类似于diff的程序来查找这些文件之间的差异 因为我还没有找到一个不会因为内存耗尽而爆炸的diff程序,所以我决定最好的办法是在关闭标记后添加CRLFs 我编写了一个python脚本来逐字符读取字符,并在“>”之后添加新行。问题是我在单核PC上运行这个程序大约是1995年,或者是一些荒谬的事情,当我同时进行转换时,它的处理速度只有20MB/小时 如果用C#/C/C++编写此代码,会有什么好处吗?如果没有,
编辑: 这是我的处理函数的代码
def read_and_format(inputfile, outputfile):
''' Open input and output files, then read char-by-char and add new lines after ">" '''
infile = codecs.open(inputfile,"r","utf-8")
outfile = codecs.open(outputfile,"w","utf-8")
char = infile.read(1)
while(1):
if char == "":
break
else:
outfile.write(char)
if(char == ">"):
outfile.write("\n")
char = infile.read(1)
infile.close()
outfile.close()
EDIT2:
谢谢你的精彩回复。增加读取大小带来了难以置信的速度提升。问题已解决。所有提到的语言通常会在某个时候恢复到C运行时库,以便逐字节访问文件。用C写这篇文章可能是最快的选择 然而,我怀疑它能否提供巨大的速度提升。如果你做得正确的话,Python的速度相当快 真正获得高速提升的主要方法是引入线程。如果您在一个线程中以一个大的块从文件中读取数据,并且有一个单独的线程执行换行处理+差异处理,则可以显著提高此算法的速度。这可能比C++或cPython直接在C、C++或IrPython中容易实现,因为它们提供了处理线程问题的非常简单、高层次的同步工具(尤其是在使用.NET时)。 < P>可以尝试XMLDIF-< /P>
我没有将它用于如此巨大的数据,但我认为它会得到合理的优化一次读取和写入一个字符几乎总是很慢,因为磁盘是基于块的设备,而不是基于字符的设备-它将读取远远超过您要读取的一个字节,多余的零件需要丢弃 尝试一次读取和写入更多数据,比如8192字节(8KB),然后在写入之前在该字符串中查找和添加换行符-您应该可以节省大量性能,因为所需的I/O要少得多
正如LBushkin所指出的,您的I/O库可能正在进行缓冲,但除非有某种形式的文档表明确实发生了这种情况(用于读写),否则在用不同的语言重写之前尝试一下是相当容易的。而不是逐字节读取,这会导致每次读取字节都会访问磁盘,尝试一次读取~20 MB,然后在上面执行搜索+替换:) 您可能可以在记事本中执行此操作
Billy3对于您描述的问题类型,我怀疑您用于比较数据的算法将比I/O模型或语言产生更显著的影响。事实上,这里的字符串分配和搜索可能比其他任何东西都要昂贵 在你自己写这篇文章之前,有一些一般性的建议:
using System;
using System.IO;
namespace ExpandBrackets
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 2)
{
using( StreamReader input = new StreamReader( args[0] ) )
using( StreamWriter output = new StreamWriter( args[1] ) )
{
int readSize = 0;
int blockSize = 100000;
char[] inBuffer = new char[blockSize];
char[] outBuffer = new char[blockSize*3];
while( ( readSize = input.ReadBlock( inBuffer, 0, blockSize ) ) > 0 )
{
int writeSize = TransformBlock( inBuffer, outBuffer, readSize );
output.Write( outBuffer, 0, writeSize );
}
}
}
else
{
Console.WriteLine( "Usage: repchar {inputfile} {outputfile}" );
}
}
private static int TransformBlock( char[] inBuffer, char[] outBuffer, int size )
{
int j = 0;
for( int i = 0; i < size; i++ )
{
outBuffer[j++] = inBuffer[i];
if (inBuffer[i] == '>') // append CR LF
{
outBuffer[j++] = '\r';
outBuffer[j++] = '\n';
}
}
return j;
}
}
}
使用系统;
使用System.IO;
命名空间扩展方括号
{
班级计划
{
静态void Main(字符串[]参数)
{
如果(args.Length==2)
{
使用(StreamReader输入=新StreamReader(args[0]))
使用(StreamWriter输出=新StreamWriter(args[1]))
{
int readSize=0;
int blockSize=100000;
char[]inBuffer=新字符[块大小];
char[]exputffer=新字符[blockSize*3];
而((readSize=input.ReadBlock(inBuffer,0,blockSize))>0)
{
int writeSize=TransformBlock(inBuffer、exputffer、readSize);
output.Write(突发,0,writeSize);
}
}
}
其他的
{
WriteLine(“用法:repchar{inputfile}{outputfile}”);
}
}
私有静态整型转换块(字符[]inBuffer,字符[]exputffer,整型大小)
{
int j=0;
对于(int i=0;i')//追加CR-LF
{
exputffer[j++]='\r';
line(i+0) == line(j+0)
line(i+0) == line(j+1)
line(i+1) == line(j+0)
line(i+0) == line(j+2)
line(i+1) == line(j+1)
line(i+2) == line(j+0)