GoLang中的Sax解析-速度慢

Given the following code in C# / .NET Core 2.1

class Program
{
    static void Main(string[] args)
    {
        var totalAmountSeconds = 0;

        using (var reader = XmlReader.Create(@"C:\Users\kevin\Desktop\temp\XML.xml"))
        {
            var stopWatch = new Stopwatch();
            var elementCounter = 0;

            stopWatch.Start();

            foreach (var element in XmlReaderUtils.EnumerateAxis(reader, new[] { "Node" }))
            {
                elementCounter += 1;
            }

            stopWatch.Stop();
            totalAmountSeconds += stopWatch.Elapsed.Seconds;

            Console.WriteLine("Total '<Node />' elements: " + elementCounter);
        }

        using (var reader = XmlReader.Create(@"XML.xml"))
        {
            var stopWatch = new Stopwatch();
            var elementCounter = 0;

            stopWatch.Start();

            foreach (var element in XmlReaderUtils.EnumerateAxis(reader, new[] { "ArticleGroup" }))
            {
                elementCounter += 1;
            }

            stopWatch.Stop();
            totalAmountSeconds += stopWatch.Elapsed.Seconds;

            Console.WriteLine("Total '<ArticleGroup />' elements: " + elementCounter);
        }

        Console.WriteLine("Total amount of required seconds: " + totalAmountSeconds);
    }
}

public static class XmlReaderUtils
{
    public static IEnumerable<XElement> EnumerateAxis(XmlReader reader,
        string[] elements)
    {
        reader.MoveToContent();

        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    if (!elements.Contains(reader.Name)) continue;

                    yield return XNode.ReadFrom(reader) as XElement;

                    break;
            }
        }
    }
}

I do believe that an exact copy of this code in GoLang should be the following:

package main

import (
    "encoding/xml"
    "fmt"
    "os"
    "time"
)

func main() {
    start := time.Now()

    xmlFile, _ := os.Open("XML.xml")
    defer xmlFile.Close()

    decoder := xml.NewDecoder(xmlFile)

    amountOfElements := 0
    for {
        t, _ := decoder.Token()
        if t == nil {
            break
        }

        // Inspect the type of the token just read.
        switch se := t.(type) {
        case xml.StartElement:
            if se.Name.Local == "Node" {
                amountOfElements++
            }
        }
    }

    fmt.Printf("Total '<Node />' elements: %v
", amountOfElements)

    xmlFile, _ = os.Open("XML.xml")
    defer xmlFile.Close()

    decoder = xml.NewDecoder(xmlFile)

    amountOfElements = 0
    for {
        t, _ := decoder.Token()
        if t == nil {
            break
        }

        // Inspect the type of the token just read.
        switch se := t.(type) {
        case xml.StartElement:
            if se.Name.Local == "ArticleGroup" {
                amountOfElements++
            }
        }
    }

    fmt.Printf("Total '<ArticleGroup />' elements: %v
", amountOfElements)

    fmt.Printf("Total elapsed time: %v", time.Since(start))
}

The code execution in .NET takes 1 minutes, while in GoLang, it takes 2 minutes. The .NET version is built using Release configuration, go GoLang a go build is executed.

I expected GoLang to be faster but indeed it turned out to be slower? Is this normal or am I missing something?

xml.NewDecoder contains two methods to read XML token from file - Token() and RawToken().

Tocken() contains some additional checks for StartElement and EndElement match and translate name space prefixes to their corresponding URLs.

Try RawToken() if you do note these features.

P.S. In C# you read 2 different files, in GO you read the same file twice. Can it be that second file is smaller/simpler in C# sample?