Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
性能-Python与C#/C++/逐字符读取_C#_Python_Performance_Character - Fatal编程技术网

性能-Python与C#/C++/逐字符读取

性能-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++编写此代码,会有什么好处吗?如果没有,

所以我有这些巨大的XML文件(我的意思是1.5GB+),它们没有CRLF。我正在尝试运行一个类似于diff的程序来查找这些文件之间的差异

因为我还没有找到一个不会因为内存耗尽而爆炸的diff程序,所以我决定最好的办法是在关闭标记后添加CRLFs

我编写了一个python脚本来逐字符读取字符,并在“>”之后添加新行。问题是我在单核PC上运行这个程序大约是1995年,或者是一些荒谬的事情,当我同时进行转换时,它的处理速度只有20MB/小时

如果用C#/C/C++编写此代码,会有什么好处吗?如果没有,是否有人知道将逐字节运行的diff程序?谢谢


编辑:

这是我的处理函数的代码

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模型或语言产生更显著的影响。事实上,这里的字符串分配和搜索可能比其他任何东西都要昂贵

在你自己写这篇文章之前,有一些一般性的建议:

  • 如果有可用的机器,请尝试在速度更快的机器上运行。这将产生巨大的变化
  • 在线查找现有的用于执行XML差异的工具。。。不要自己写
  • 如果您打算用C#(或Java或C/C++)编写此代码,我将执行以下操作:

  • 一次将相当大的块读入内存(假设在200k到1M之间)
  • 分配一个两倍于该大小的空块(假设每个字符的最坏情况是“>”)
  • 从输入块复制到输出块,在每个'>'字符后有条件地追加一个CRLF
  • 将新块写入磁盘
  • 重复此操作,直到处理完所有数据
  • 此外,您还可以编写这样一个在多个线程上运行的程序,这样,一旦线程在内存中执行CRLF插入,就可以从磁盘中读取一个单独的线程。这种类型的并行化很复杂。。。所以我只会在你真的需要最大性能的时候才这么做

    如果您需要,这里有一个非常简单的C#程序可以帮助您开始。它在命令行上接受输入文件路径和输出路径,并执行您要查找的替换('>'==>CRLF)。此示例还有很多需要改进的地方(并行处理、流式处理、一些验证等)。。。但这应该是一个不错的开始

    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;iline(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)