XML 写越来越慢

XML Write Getting Steadily Slower

我想我之前把这个复杂化了。

正在将多个列表的内容写入一个 XML 文件。写一个结果需要一毫秒,但写 100 个结果几乎需要一分钟,这是没有意义的。我添加了一个计数器,每次写入都比上一次慢。

我找不到瓶颈。我不明白是什么在减慢它的速度,而且我只需要自己手动将数据写入记事本就可以了。

我试过:

*不检查是否存在 Temp.xml 来设置 tree/root,但没有任何区别。

*使用相同的列表而不是多个列表以防万一导致出现异常情况。

*我认为它可能只是我的系统,所以我将它安装在 40 核疯狂级别的 SSD 服务器上,结果相同。

代码:

def filewriter():
    while 1:
            time.sleep(10)
            if OnlyOneXMLWriteCheck == 1:
                WriteThatThread = Thread(target = FileWrite)
                WriteThatThread.start()
                WriteThatThread.join()

def FileWrite():
    try:
        if os.path.exists("Temp.xml") == True:
            os.remove("Temp.xml")

        EventDumpCounter = 0

        for Eventes in EventTags:
            try:

                if os.path.exists("Temp.xml") == True:
                    tree = ET.parse("Temp.xml")
                    root = tree.getroot()
                if os.path.exists("Temp.xml") == False:
                    root = ET.Element("Refunds")
                    tree = ET.ElementTree(root)

                if float(EventCost[EventDumpCounter]) > float(Price[EventDumpCounter]):

                    if "Horse" in EventTags[EventDumpCounter]:
                        Eventes = ET.SubElement(root, "Event", type = EventTags[EventDumpCounter])
                        ET.SubElement(Eventes, "EventTime").text = str(EventTimes[EventDumpCounter])
                        ET.SubElement(Eventes, "EventName").text = str(EventName[EventDumpCounter])
                        ET.SubElement(Eventes, "EventLoc").text = str(EventLoc[EventDumpCounter])
                        ET.SubElement(Eventes, "EventSpace").text = str(EventSpace[EventDumpCounter])
                        ET.SubElement(Eventes, "EventCost").text = str(EventCost[EventDumpCounter])
                        ET.SubElement(Eventes, "EventPrice").text = str(EventPrice[EventDumpCounter])
                        ET.SubElement(Eventes, "EventParking").text = str(EventParking[EventDumpCounter])
                        ET.SubElement(Eventes, "EventDist").text = str(EventDist[EventDumpCounter])
                        tree.write("Temp.xml")

                EventDumpCounter +=1

            except:
                print "Problem writing XML"

    #except:
    except WindowsError, e:
        print "Problem creating XML 2"
        #e = sys.exc_info()[0]
        print e

KeepWritingFiles = Thread(target = filewriter)
KeepWritingFiles.start()

/更新:

在下面的评论之后,有人建议每次解析 XML 都会减慢速度。我这样做是为了它可以开始一个新的 XML 或附加到现有的,但我改为:

   if os.path.exists("Temp.xml") == True:
            if OnlyParseOnce == 0:
                print "opening file"
                OnlyParseOnce = 1
                tree = ET.parse("Temp.xml")
                root = tree.getroot()
        if os.path.exists("Temp.xml") == False:
            root = ET.Element("Events")
            tree = ET.ElementTree(root)

"opening file" 只显示一次,这意味着它不会不断地解析文件,而且速度仍然很慢。我想知道是否 "os.path.exists" 是瓶颈。

如果我手动设置的话

 root = ET.Element("Refunds")
  tree = ET.ElementTree("Events")

它在一秒钟内飞过相同数量的数据。一点时间也没有。但是这样它就不会附加到它不断重写的现有文件中。所以它可能是 os.path.exists 或者可能只是因为我正在写一个结果而不是创建一个更大的文件。

您的代码在每个循环结束时用 tree.write("Temp.xml") 写入文档,然后用 tree = ET.parse("Temp.xml") 再次读取和解析它。这完全没有意义,因为 tree 已经在内存中,不需要重建。随着文档的增长,写入和读取的成本上升,性能下降。只需使用内存中的 tree 对象并延迟写入,直到循环完成。

def FileWrite():
    try:
        if os.path.exists("Temp.xml") == True:
            os.remove("Temp.xml")
        root = ET.Element("Refunds")
        tree = ET.ElementTree(root)

        EventDumpCounter = 0

        for Eventes in EventTags:
            try:
                if float(EventCost[EventDumpCounter]) > float(Price[EventDumpCounter]):
                    if "Horse" in EventTags[EventDumpCounter]:
                        Eventes = ET.SubElement(root, "Event", type = EventTags[EventDumpCounter])
                        ET.SubElement(Eventes, "EventTime").text = str(EventTimes[EventDumpCounter])
                        ET.SubElement(Eventes, "EventName").text = str(EventName[EventDumpCounter])
                        ET.SubElement(Eventes, "EventLoc").text = str(EventLoc[EventDumpCounter])
                        ET.SubElement(Eventes, "EventSpace").text = str(EventSpace[EventDumpCounter])
                        ET.SubElement(Eventes, "EventCost").text = str(EventCost[EventDumpCounter])
                        ET.SubElement(Eventes, "EventPrice").text = str(EventPrice[EventDumpCounter])
                        ET.SubElement(Eventes, "EventParking").text = str(EventParking[EventDumpCounter])
                        ET.SubElement(Eventes, "EventDist").text = str(EventDist[EventDumpCounter])
                EventDumpCounter +=1

            except: # bad idea, you just supressed debug info
                # potential problem = since you supress the error and continue
                # processing but EventDumpCounter never advanced, you could
                # get stuck in an infinite error loop.
                print "Problem writing XML"

        tree.write("Temp.xml")

    #except:
    except WindowsError, e:
        print "Problem creating XML 2"
        #e = sys.exc_info()[0]
        print e