I was considering to adapt go for my future projects for performance reason but there is a big surprise: go's running time is 13.974427s while pythons elapsed time is just 6.593028783798218s Less then a half!
The XML file size is over 300 MB. Here is the pythons's code:
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)
and here is the simplified go code:
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))
}
Why is this big difference?