当我在.NET应用程序中查找配置时,我希望在某处找到一个名为MyApp.exe.config的XML文件。 坚持使用principle of least surprise,我更倾向于XML序列化而不是JSON。还有一个额外的好处是,XML格式的配置可以适应Configuration API的工作。否则两者都有同样的支持:平台不可知、良好的解析器、基于文本等。 只有当性能成为一个问题时,它才是一个问题。我喜欢在编写代码之前识别潜在的问题,但这通常是由体系结构决策引入的性能问题。像这样的东西,小而相当独立,如果它被证明是一个剖析中的问题,那么改变它并不困难。
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;
}
7条答案
按热度按时间h43kikqp1#
好了,不用猜了,我有答案了。下面是测试程序:
这是测量的输出:
JSON在一次迭代后总是快一点,1000次迭代后就没有什么区别了,10000次迭代后,XML明显更快。
在这一点上,我不能解释为什么JSON一次一个时会更快,但XML重复时会更快。可能是由于缓存或库中的一些奇特之处。您可以看到,JsonSerializer线性扩展,迭代次数增加10个数量级,运行时间线性增加10个数量级。XmlSerializer的行为不同,其性能并不以线性方式缩放。
我重复了几次,都得到了同样的结果。
因此,如果只解析一个对象一次,那么JSON会稍微好一点。但是如果重复解析对象,那么XML可能会表现得更好。虽然我还没有测试如果对象值随着每次迭代而改变会发生什么,但这可能会造成不同。
另外请注意,我在这里使用的是原生的Runtime.Serialization库。其他库可能会产生不同的结果。
编辑:我只是在每次调用字符串时生成一个新的Guid和随机Int时尝试了这个方法。这对单次或10000次迭代测试没有什么区别。但是对于1000次迭代,JSON大约快了1ms。所以看起来XML序列化器确实在缓存值。
hgncfbus2#
当我在.NET应用程序中查找配置时,我希望在某处找到一个名为MyApp.exe.config的XML文件。
坚持使用principle of least surprise,我更倾向于XML序列化而不是JSON。还有一个额外的好处是,XML格式的配置可以适应Configuration API的工作。否则两者都有同样的支持:平台不可知、良好的解析器、基于文本等。
只有当性能成为一个问题时,它才是一个问题。我喜欢在编写代码之前识别潜在的问题,但这通常是由体系结构决策引入的性能问题。像这样的东西,小而相当独立,如果它被证明是一个剖析中的问题,那么改变它并不困难。
d7v8vwbk3#
Json的可读性可能比xml差一些,但是Json生成的文件更小。所以如果你需要通过网络发送文件,Json可能是更好的选择,或者如果你想能够阅读它,XML更好。另一个好处是,在.NET 4中你有dynamic关键字,你可以直接将你的Json转换成C#对象。
cotxawn74#
在我看来,一切都取决于您需要做什么以及如何实现,这里有一篇比较JSON和XML很好的文章。
祝你好运
https://dzone.com/articles/json-vs-xml-net-developer%e2%80%99s
lfapxunr5#
这是对2014年@Wedge答案的更新。
它是用.NET 6.0写的,也利用了流行的
Newtonsoft.Json
库,我还增加了迭代次数,以前是1、1,000、10,000,这个版本现在也是100,000、10,000,000、1,000,000次迭代,但还是很不科学,不现实。下面是使用的代码。如果您想重现此错误,请确保将
Newtonsoft.Json
导入到您的项目中。现在是性能指标评测结果:
正如您所看到的,在Newtonsoft.Json中执行单个序列化非常慢-几乎慢10倍。* 然而 *,经过多次迭代,这个数字显著下降,以至于Newtonsoft.Json明显赢家。
同样,这是不科学的,也是不现实的,但确实给予了使用Newtonsoft.Json的序列化性能的一些概念。
如果有人想指出我的答案中的问题,提出改进其中任何一个的建议,请让我知道。
bgtovc5b6#
序列化的成本大致相同。这不太可能是一个明显的差异。使用您的用户将感到最舒适的修改格式(因为它是一个配置文件)。
真实的的性能差异可能发生在需要通过网络发送JSON或XML时,性能取决于发送的内容的多少,由于JSON通常比XML更简洁,因此它在网络上的性能通常更好。
vc9ivgsu7#
这基本上与answer上解释的代码相同,但由于我读到的每个答案似乎都只运行代码一次,并且从1次迭代开始,似乎有一个结论是运行1次迭代比1000次迭代更糟糕,因此我决定运行它多次,结果如下:
如果从100,000开始,您在第一次迭代中获得相同的预期性能:
我不能给予一个非常知情的答复,所以我保持原样。