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

0 投票
8 回答
3723 浏览
提问于 2025-04-15 13:53

我有一些超大的XML文件(说大就是指1.5GB以上),而且这些文件没有换行符。我想用一个类似于比较工具的程序来找出这些文件之间的不同之处。

因为我还没找到一个不会因为内存不足而崩溃的比较程序,所以我决定在每个结束标签后面加上换行符。

我写了一个Python脚本,逐个字符读取,并在'>'后面添加换行符。问题是我在一台大约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()

补充2:感谢大家的精彩回复。增加读取的大小让速度提升了很多,问题解决了。

8 个回答

1

与其一个字节一个字节地读取,这样每读取一个字节就要访问一次硬盘,不如一次性读取大约20MB的数据,然后在这些数据上进行搜索和替换,这样效率会高很多 :)

你可能可以在记事本里做到这一点……

Billy3

3

你为什么不直接用sed呢? 可以用这个命令: cat giant.xml | sed 's/>/>\x0a\x0d/g' > giant-with-linebreaks.xml

11

一次只读写一个字符通常会很慢,因为硬盘是以块为单位来工作的,而不是一个一个字符来处理。也就是说,硬盘在读取数据时,会一次性读取比你需要的那个字节多得多的数据,然后多余的部分就得被丢掉。

试着一次读写更多的数据,比如8192个字节(8KB),然后在这段字符串中找到并添加换行符,再把它写出去。这样做可以大大提高性能,因为这样需要的输入输出操作会少很多。

正如LBushkin所说,你的输入输出库可能会进行缓存处理,但除非有一些文档说明确实存在这种情况(无论是读取还是写入),否则在换用其他语言之前,尝试一下这个方法是相对简单的。

撰写回答