XPath vs Deserialization: qual é o melhor em desempenho para operações de leitura

votos
7

Eu estou passando pequenos documentos XML (2-10 KB) como entrada para um serviço WCF. Agora eu tenho duas opções para ler valores de dados de XML de entrada

  1. Desserializar a um objeto fortemente tipado e usar as propriedades do objeto para acessar valores
  2. usar XPath para acessar valores

qual abordagem é mais rápido? algumas estatísticas para apoiar a sua resposta seria ótimo.

Publicado 10/11/2008 em 12:59
fonte usuário
Em outras línguas...                            


3 respostas

votos
4

Há uma terceira opção de furar com XML, mas consulta com qualquer API que você está usando XML - por exemplo, LINQ to XML faz consultas relativamente simples no código.

Você já analisado o texto em um documento XML?

Você está convencido de que este é realmente um gargalo de desempenho significativa em seu código? (Por exemplo, se você estiver em seguida, falar com um banco de dados, então não se preocupe com isso para começar - basta fazê-lo funcionar da maneira mais simples em primeiro lugar)

São as consultas sempre o mesmo, ou são dinâmica de alguma forma?

Você tem um equipamento de teste com mensagens e consultas realistas? Se não, você precisa de um, a fim de avaliar as respostas dadas aqui com os seus dados. Se você fizer isso, eu esperaria que seja razoavelmente fácil de experimentar por si mesmo :)

Respondeu 10/11/2008 em 13:04
fonte usuário

votos
7

Eu desserializá-lo.

Se você usar o XPath, você vai desserializar (ou "carga") para XmlDocument ou algo assim mesmo. Assim, ambas as soluções usar desserialização tempo. Depois de feito isso, xpath será mais lento por causa do tempo gasto analisar essa seqüência, resolução de nomes, a execução de funções e assim por diante. Além disso, se você vai com XPath, você não recebe nenhum tipo de segurança. O compilador não pode verificar a sintaxe XPath para você.

Se você usa XmlSerializer e classes, você obter tipagem estática. acesso muito rápido a você dados, e se você quiser consultá-los com o XPath, ainda existem maneiras de fazer isso.

Além disso, eu gostaria de dizer que seu código provavelmente seria mais fácil de entender com classes.

O único inconveniente é que o XML tem de obedecer ao mesmo esquema o tempo todo, mas que pode não ser um problema real no seu caso.

Eu espero que você perdoar a ausência de estatísticas, acho que os argumentos são fortes o suficiente, sem exemplos. Se você quer uma resposta definitiva, tente ambos e manter um cronômetro pronto.

Respondeu 21/11/2008 em 00:16
fonte usuário

votos
1

Aqui estão 4 casos, todas as vezes em carrapatos e colocação:

  • XmlSerializer (Slowest 4)
  • Implementar IXmlSerializable (3)
  • Mão Laminados (Custom) (1º)
  • XElement (2)

objeto da amostra foi lida 1000 vezes.

Se você se importa? Para maioria dos casos, use as serializers padrão que são construídos em .net. Não há necessidade de se desviar e que vai produzir a quantidade mínima de código. Aqueles devem ser mais do que suficiente, oferecer segurança de tipo e livre-se de fazer as coisas mais significativas com o seu tempo. Em alguns casos, XElement pode ser útil se você deseja cereja escolher certos elementos de dados fora de uma grande estrutura XML, mas mesmo assim deve-se colocar esses elementos em um DTO fortemente tipado. Mas tenha em mente, todos os métodos são muito rápidos. Eu pessoalmente serializado um modelo de objeto extremamente ampla e profunda (bem mais de 400 clases) em apenas alguns milissegundos. Para objetos menores e banais, será vezes sub resposta ms. XMLSerializer aquecer é mais lento do que os outros, mas pode-se reduzir com SGEN ou fazer alguma inicialização na inicialização.

Detalhes e código ...

xml Serializer

[Serializable]
    public class FoobarXml
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public bool IsContent { get; set; }

        [XmlElement(DataType = "date")]
        public DateTime BirthDay { get; set; }
    }

Primeira Vez: 2448965

1000 Leia média: 245

IXmlSerializable

 public class FoobarIXml : IXmlSerializable
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public bool IsContent { get; set; }
        public DateTime BirthDay { get; set; }

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            var isEmptyElement = reader.IsEmptyElement;
            reader.ReadStartElement();
            if (!isEmptyElement)
            {
                Name = reader.ReadElementString("Name");

                int intResult;
                var success = int.TryParse(reader.ReadElementString("Age"), out intResult);
                if (success)
                {
                    Age = intResult;
                }

                bool boolResult;
                success = bool.TryParse(reader.ReadElementString("IsContent"), out boolResult);
                if (success)
                {
                    IsContent = boolResult;
                }
                DateTime dateTimeResult;
                success = DateTime.TryParseExact(reader.ReadElementString("BirthDay"), "yyyy-MM-dd", null,
                    DateTimeStyles.None, out dateTimeResult);
                if (success)
                {
                    BirthDay = dateTimeResult;
                }
                reader.ReadEndElement(); //Must Do
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteElementString("Name", Name);
            writer.WriteElementString("Age", Age.ToString());
            writer.WriteElementString("IsContent", IsContent.ToString());
            writer.WriteElementString("BirthDay", BirthDay.ToString("yyyy-MM-dd"));
        }
    }
}

Primeira Vez: 2051813

1000 Leia média: 208

mão laminados

 public class FoobarHandRolled
    {
        public FoobarHandRolled(string name, int age, bool isContent, DateTime birthDay)
        {
            Name = name;
            Age = age;
            IsContent = isContent;
            BirthDay = birthDay;
        }

        public FoobarHandRolled(string xml)
        {
            if (string.IsNullOrWhiteSpace(xml))
            {
                return;
            }

            SetName(xml);
            SetAge(xml);
            SetIsContent(xml);
            SetBirthday(xml);
        }

        public string Name { get; set; }
        public int Age { get; set; }
        public bool IsContent { get; set; }
        public DateTime BirthDay { get; set; }

        /// <summary>
        ///     Takes this object and creates an XML representation.
        /// </summary>
        /// <returns>An XML string that represents this object.</returns>
        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.Append("<FoobarHandRolled>");

            if (!string.IsNullOrWhiteSpace(Name))
            {
                builder.Append("<Name>" + Name + "</Name>");
            }

            builder.Append("<Age>" + Age + "</Age>");
            builder.Append("<IsContent>" + IsContent + "</IsContent>");
            builder.Append("<BirthDay>" + BirthDay.ToString("yyyy-MM-dd") + "</BirthDay>");
            builder.Append("</FoobarHandRolled>");

            return builder.ToString();
        }

        private void SetName(string xml)
        {
            Name = GetSubString(xml, "<Name>", "</Name>");
        }

        private void SetAge(string xml)
        {
            var ageString = GetSubString(xml, "<Age>", "</Age>");
            int result;
            var success = int.TryParse(ageString, out result);
            if (success)
            {
                Age = result;
            }
        }

        private void SetIsContent(string xml)
        {
            var isContentString = GetSubString(xml, "<IsContent>", "</IsContent>");
            bool result;
            var success = bool.TryParse(isContentString, out result);
            if (success)
            {
                IsContent = result;
            }
        }

        private void SetBirthday(string xml)
        {
            var dateString = GetSubString(xml, "<BirthDay>", "</BirthDay>");
            DateTime result;
            var success = DateTime.TryParseExact(dateString, "yyyy-MM-dd", null, DateTimeStyles.None, out result);
            if (success)
            {
                BirthDay = result;
            }
        }

        private string GetSubString(string xml, string startTag, string endTag)
        {
            var startIndex = xml.IndexOf(startTag, StringComparison.Ordinal);
            if (startIndex < 0)
            {
                return null;
            }

            startIndex = startIndex + startTag.Length;

            var endIndex = xml.IndexOf(endTag, StringComparison.Ordinal);
            if (endIndex < 0)
            {
                return null;
            }

            return xml.Substring(startIndex, endIndex - startIndex);
        }
    }

Primeira Vez: 161105

1000 Leia média: 29

XElement

        var xDoc = XElement.Parse(xml);

        var nameElement = xDoc.Element("Name");
        var ageElement = xDoc.Element("Age");
        var isContentElement = xDoc.Element("IsContent");
        var birthDayElement = xDoc.Element("BirthDay");

        string name = null;
        if (nameElement != null)
        {
            name = nameElement.Value;
        }
        var age = 0;
        if (ageElement != null)
        {
            age = int.Parse(ageElement.Value);
        }
        var isContent = false;
        if (isContentElement != null)
        {
            isContent = bool.Parse(isContentElement.Value);
        }
        var birthDay = new DateTime();
        if (birthDayElement != null)
        {
            birthDay = DateTime.ParseExact(birthDayElement.Value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
        }

Primeira Vez: 247024

1000 Leia média: 113

Respondeu 06/06/2016 em 19:27
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more