Json和XML序列化,什么是更好的性能

本文关键字:更好 性能 什么 XML 序列化 Json | 更新日期: 2023-09-27 18:36:31

我必须在文件中存储一些配置信息。在 C# 代码中,配置数据由类表示,在文件中,我将以 json 或 xml 格式保存此类。 那么,序列化 json 或 xml 的最佳性能是什么?

Json和XML序列化,什么是更好的性能

好吧,与其猜测,我有答案。 这是测试程序:

class Program
{
    static void Main(string[] args)
    {
        string xmlConfig = "";
        string jsonConfig = "";
        Config myConfig = new Config()
        {
            value = "My String Value",
            DateStamp = DateTime.Today,
            counter = 42,
            Id = Guid.NewGuid()
        };
        // Make both strings
        DataContractSerializer xmlSerializer = new DataContractSerializer(typeof(Config));
        using (MemoryStream xmlStream = new MemoryStream())
        {
            xmlSerializer.WriteObject(xmlStream, myConfig);
            xmlConfig = Encoding.UTF8.GetString(xmlStream.ToArray());
        }
        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Config));
        using (MemoryStream jsonStream = new MemoryStream())
        {
            jsonSerializer.WriteObject(jsonStream, myConfig);
            jsonConfig = Encoding.UTF8.GetString(jsonStream.ToArray());
        }
        // Test Single
        var XmlSingleTimer = Stopwatch.StartNew();
        SerializeXML(xmlConfig, 1);
        XmlSingleTimer.Stop();
        var JsonSingleTimer = Stopwatch.StartNew();
        SerializeJSON(jsonConfig, 1);
        JsonSingleTimer.Stop();
        // Test 1000
        var XmlTimer = Stopwatch.StartNew();
        SerializeXML(xmlConfig, 1000);
        XmlTimer.Stop();
        var JsonTimer = Stopwatch.StartNew();
        SerializeJSON(jsonConfig, 1000);
        JsonTimer.Stop();
        // Test 10000
        var XmlTimer2 = Stopwatch.StartNew();
        SerializeXML(xmlConfig, 10000);
        XmlTimer2.Stop();
        var JsonTimer2 = Stopwatch.StartNew();
            SerializeJSON(jsonConfig, 10000);
        JsonTimer2.Stop();
        Console.WriteLine(String.Format("XML Serialization Single: {0}ms", XmlSingleTimer.Elapsed.TotalMilliseconds));
        Console.WriteLine(String.Format("JSON Serialization Single: {0}ms", JsonSingleTimer.Elapsed.TotalMilliseconds));
        Console.WriteLine();
        Console.WriteLine(String.Format("XML Serialization 1000: {0}ms", XmlTimer.Elapsed.TotalMilliseconds));
        Console.WriteLine(String.Format("JSON Serialization 1000: {0}ms ", JsonTimer.Elapsed.TotalMilliseconds));
        Console.WriteLine();
        Console.WriteLine(String.Format("XML Serialization 10000: {0}ms ", XmlTimer2.ElapsedMilliseconds));
        Console.WriteLine(String.Format("JSON Serialization 10000: {0}ms ", JsonTimer2.ElapsedMilliseconds));
    }
    public static void SerializeXML(string xml, int iterations)
    {
        DataContractSerializer xmlSerializer = new DataContractSerializer(typeof(Config));
        for (int i = 0; i < iterations; i++)
        {
            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                Config serialized = (Config)xmlSerializer.ReadObject(stream);
            }
        }
    }
    public static void SerializeJSON(string json, int iterations)
    {
        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Config));
        for (int i = 0; i < iterations; i++)
        {
            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                Config serialized = (Config)jsonSerializer.ReadObject(stream);
            }
        }
    }
}
public class Config
{
    public string value;
    public DateTime DateStamp;
    public int counter;
    public Guid Id;
}

这是测量的输出:

XML Serialization Single: 2.3764ms
JSON Serialization Single: 2.1432ms
XML Serialization 1000: 13.7754ms
JSON Serialization 1000: 13.747ms
XML Serialization 10000: 100ms
JSON Serialization 10000: 134ms

JSON 在 1 次迭代后一直快一点点。 经过 1000 次迭代,真的没有区别。 经过 10000 次迭代后,XML 显然更快。

在这一点上,我无法解释为什么 JSON 一次一个会更快,但 XML 在重复时会更快。 可能是由于缓存或库中的一些花哨的东西。您可以看到 JsonSerializer 呈线性缩放,将迭代次数增加 10 个数量级,将运行时间线性增加 10 个数量级。 但是,XmlSerializer的行为有所不同,其性能并未以线性方式扩展。

我重复了几次,并始终得到相同的结果。

因此,教训是,如果您只解析一次单个对象,那么 JSON 会稍微好一些。 但是,如果要重复分析对象,则 XML 的性能可能会更好。 虽然,我还没有测试如果对象值在每次迭代中发生变化会发生什么,这可能会有所不同。

另请注意,我在这里使用的是本机 Runtime.Serialization 库。 其他库可能会产生不同的结果。

编辑:我刚刚尝试了这个,同时每次调用字符串时都会生成新的 Guid 和随机 Int。 它对单个或 10000 次迭代测试没有区别。 但是对于 1000 次迭代,JSON 快了大约 1 毫秒。 因此,看起来 XML 序列化程序确实在缓存值。

当我在.NET应用程序中查找配置时,我希望在名为MyApp.exe.config的地方找到一个XML文件。

坚持最小惊喜的原则,我更喜欢XML序列化而不是JSON。还有一个额外的好处,即 XML 格式的配置可以适应与配置 API 一起使用。否则,两者都具有相同的支持类型:与平台无关,体面的解析器,基于文本等。

性能只有在成为问题时才是一个问题。我喜欢在编码之前识别潜在问题,但这通常是关于架构决策引入的性能问题。像这样的东西,小而相当独立,如果它被证明是分析中的问题,那么改变起来并不困难。

这是

对@Wedge 2014年答案的更新。

它是用.NET 6.0编写的,还利用了流行的Newtonsoft.Json库。我还增加了迭代次数。以前是 1、1,000 和 10,000。这个版本现在也做了

100,000,000,000和10,000,000次迭代,但仍然非常不科学,不现实。

下面是使用的代码。如果要重现此内容,请务必将Newtonsoft.Json导入到项目中。

using Newtonsoft.Json;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
Config myConfig = new Config()
{
    value = "My String Value",
    DateStamp = DateTime.Today,
    counter = 42,
    Id = Guid.NewGuid()
};
// Xml serializer
string xmlConfig = "";
var xmlSerializer = new DataContractSerializer(typeof(Config));
using (var xmlStream = new MemoryStream())
{
    xmlSerializer.WriteObject(xmlStream, myConfig);
    xmlConfig = Encoding.UTF8.GetString(xmlStream.ToArray());
}
// Json serializer
string jsonConfig = "";
var jsonSerializer = new DataContractJsonSerializer(typeof(Config));
using (var jsonStream = new MemoryStream())
{
    jsonSerializer.WriteObject(jsonStream, myConfig);
    jsonConfig = Encoding.UTF8.GetString(jsonStream.ToArray());
}
// Newtonsoft.Json serializer.
string newtonsoftJsonConfig = "";
var newtonsoftJsonSerializer = new JsonSerializer();
using (var newtonSoftMemoryStream = new MemoryStream())
using (var writer = new StreamWriter(newtonSoftMemoryStream))
using (var newtonsoftJsonWriter = new JsonTextWriter(writer))
{
    newtonsoftJsonSerializer.Serialize(newtonsoftJsonWriter, myConfig);
    newtonsoftJsonWriter.Flush();
    newtonSoftMemoryStream.Position = 0;
    newtonsoftJsonConfig = Encoding.UTF8.GetString(newtonSoftMemoryStream.ToArray());
}
// Create a group of 5 different tests.
int[] counterArray = { 1, 1000, 10000, 100000, 1000000, 10000000 };
foreach (var iterations in counterArray)
{
    // Serialize XML.
    var xmlTimer = Stopwatch.StartNew();
    SerializeXML(xmlConfig, iterations);
    xmlTimer.Stop();
    // Serialize JSON.
    var jsonTimer = Stopwatch.StartNew();
    SerializeJSON(jsonConfig, iterations);
    jsonTimer.Stop();
    // Serialize JSON (Newtonsoft).
    var newtonsoftJsonTimer = Stopwatch.StartNew();
    SerializeNewtonsoftJson(newtonsoftJsonConfig, iterations);
    newtonsoftJsonTimer.Stop();
    Console.WriteLine($"XML Serialization {iterations}: {xmlTimer.Elapsed.TotalMilliseconds}ms");
    Console.WriteLine($"JSON Serialization {iterations}: {jsonTimer.Elapsed.TotalMilliseconds}ms");
    Console.WriteLine($"Newtonsoft.Json Serialization {iterations}: {newtonsoftJsonTimer.Elapsed.TotalMilliseconds}ms");
    Console.WriteLine();
}
static void SerializeXML(string xml, int iterations)
{
    var xmlSerializer = new DataContractSerializer(typeof(Config));
    for (var i = 0; i < iterations; i++)
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
        var serialized = (Config)xmlSerializer.ReadObject(stream);
    }
}
static void SerializeJSON(string json, int iterations)
{
    var jsonSerializer = new DataContractJsonSerializer(typeof(Config));
    for (var i = 0; i < iterations; i++)
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
        var serialized = (Config)jsonSerializer.ReadObject(stream);
    }
}
static void SerializeNewtonsoftJson(string json, int iterations)
{
    // Newtonsoft.Json serializer.
    var newtonsoftJsonSerializer = new JsonSerializer();
    for (var i = 0; i < iterations; i++)
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
        using var reader = new JsonTextReader(new StreamReader(stream, new UTF8Encoding()));
        var serialized = newtonsoftJsonSerializer.Deserialize<Config>(reader);
    }
}
public class Config
{
    public string value;
    public DateTime DateStamp;
    public int counter;
    public Guid Id;
}

现在基准测试结果:

XML Serialization 1: 4.3958ms
JSON Serialization 1: 3.3516ms
Newtonsoft.Json Serialization 1: 37.5018ms
XML Serialization 1000: 11.137ms
JSON Serialization 1000: 6.8425ms
Newtonsoft.Json Serialization 1000: 2.4205ms
XML Serialization 10000: 39.1409ms
JSON Serialization 10000: 56.8301ms
Newtonsoft.Json Serialization 10000: 21.352ms
XML Serialization 100000: 358.903ms
JSON Serialization 100000: 519.5981ms
Newtonsoft.Json Serialization 100000: 197.7238ms
XML Serialization 1000000: 3585.8248ms
JSON Serialization 1000000: 5256.336ms
Newtonsoft.Json Serialization 1000000: 2006.7546ms
XML Serialization 10000000: 36326.6082ms
JSON Serialization 10000000: 53260.1445ms
Newtonsoft.Json Serialization 10000000: 20506.9946ms

如您所见,在Newtonsoft.Json中进行单个序列化非常慢 - 几乎慢了10倍。然而,在多次迭代中,这个数字显着下降,以至于Newtonsoft.Json是一个明显的赢家。

同样,这是不科学的,也是不现实的,但确实给出了使用Newtonsoft.Json进行序列化的性能的一些想法。

如果有人想指出我的答案存在的问题,提供提高其中任何一个性能的建议,请告诉我。

Json可能比xml更难被人类读取,但json生成的文件的大小更小。因此,如果您需要通过网络发送文件,Json 可能是更好的选择,或者如果您希望能够读取它,XML 更好。另一个好处是,在 .NET 4 中,您有动态关键字,您可以将 Json 直接转换为 C# 对象。

在我看来

,一切都取决于你需要做什么以及如何实现,这是一篇比较JSON和XML的好文章。 客户端的压缩和反序列化 我选择 JSON。

祝你好运。

https://dzone.com/articles/json-vs-xml-net-developer%e2%80%99s

序列化的成本大致相同。这不太可能是一个明显的差异。使用用户最习惯修改的格式(因为它是配置文件)。

当您需要通过网络发送 JSON 或 XML 时,可能会发生真正的性能差异。然后,性能取决于您发送的内容量,并且由于JSON通常比XML更简洁,因此它通常会在网络上表现得更好。