读取大型xml文件:go encoding/xml的速度是python lxml的两倍
出于性能原因,我曾考虑将go应用于我未来的项目,但有一个大惊喜:go的运行时间为13.974427s,而pythons的运行时间仅为6.593028783798218s 不到一半 XML文件大小超过300 MB。 以下是蟒蛇的代码:读取大型xml文件:go encoding/xml的速度是python lxml的两倍,python,xml,go,Python,Xml,Go,出于性能原因,我曾考虑将go应用于我未来的项目,但有一个大惊喜:go的运行时间为13.974427s,而pythons的运行时间仅为6.593028783798218s 不到一半 XML文件大小超过300 MB。 以下是蟒蛇的代码: from lxml import objectify import time most = time.time() root = objectify.parse(open(r"c:\temp\myfile.xml", 'rb')).getroot() if h
from lxml import objectify
import time
most = time.time()
root = objectify.parse(open(r"c:\temp\myfile.xml", 'rb')).getroot()
if hasattr(root, 'BaseData'):
if hasattr(root.BaseData, 'SzTTs'):
total_records = 0
for sztt in root.BaseData.SzTTs.sztt:
total_records += 1
print("total_records", total_records)
print("Time elapsed: ", time.time()-most)
以下是简化的go代码:
package main
// An example streaming XML parser.
import (
"encoding/xml"
"fmt"
"io"
"os"
"time"
)
var inputFile = "c:\\temp\\myfile.xml"
type SzTTs struct {
Sztt []sztt
}
type sztt struct {
}
func main() {
xmlFile, err := os.Open(inputFile)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer xmlFile.Close()
d := xml.NewDecoder(xmlFile)
total1 := 0
total2 := 0
start := time.Now()
for {
// Read tokens from the XML document in a stream.
t, err := d.Token()
// If we are at the end of the file, we are done
if t == nil || err == io.EOF {
fmt.Println("The end")
break
} else if err != nil {
log.Fatalf("Error decoding token: %s", err)
}
// Inspect the type of the token just read.
switch se := t.(type) {
case xml.StartElement:
if se.Name.Local == "SzTTs" {
var p SzTTs
// decode a whole chunk of following XML into the
// variable p which is a Page (se above)
if err = d.DecodeElement(&p, &se); err != nil {
log.Fatalf("Error decoding item: %s", err)
}
for i := range p.Sztt {
total1 = i
}
}
default:
}
}
fmt.Printf("Total sztt: %d \n", total1)
fmt.Printf("Elapsed time %s", time.Since(start))
}
为什么会有这么大的差异?请详细说明我的评论-这是意料之中的 Go的
encoding/xml
是用纯Go编写的,而lxml
基本上是用C编写的。它使用Cython,它从类似Python的DSL生成C代码
2x不是一个巨大的性能差异IHO,但是如果每一个性能下降对你来说都重要,考虑使用另一个GO包——一个封装了优化的C实现。 例如,libxml(最流行的C实现之一)有几个包装器:
编码/xml
快得多
Edid(2019-07-22):这个问题启发了我,并且。您可以从缓冲文件io开始。对于其余部分:不同的语言和不同的库。xml.NewDecoder已经创建了bufio.Reader。因此,文件读取是缓冲的。Go不一定比其他语言快。如果您想采用Go,您可能正在寻找其他功能,而不仅仅是执行时间。诸如:通道、goroutine、类型安全等特性。这是优化的C库(
lxml
,Python模块是其瘦包装)和本机Go库之间的比较lxml
是用“cython”编写的,cython本质上是Pythonish DSL over C。通过使用CGO或类似的工具包装C XML解析器,应该可以获得类似的性能