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
我想我之前把这个复杂化了。
正在将多个列表的内容写入一个 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