Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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
读取大型xml文件:go encoding/xml的速度是python lxml的两倍_Python_Xml_Go - Fatal编程技术网

读取大型xml文件:go encoding/xml的速度是python lxml的两倍

读取大型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

出于性能原因,我曾考虑将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 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解析器,应该可以获得类似的性能