为什么 ServiceStack 返回 POCO 对象的速度比 .NET Remoting 返回 DataSet 的速度慢?
Why is ServiceStack returning POCO objects slower than .NET Remoting returning a DataSet?
我要从服务返回一个包含 6100 行和 156 列的数据表。
When returning it over .NET remoting it takes 1800 ms.
When returning it over .NET remoting with optimized DataSet serialization, it takes 1350 ms.
When just downloading a List<T> from ServiceStack (selfhosted) like this:
webClient.DownloadData("http://localhost:1337/hello/xx"); it takes 1400 ms
when returning the same list as really typed list - List<T>
var restClient = new JsonServiceClient("http://localhost:1337/hello");
all = restClient.Get<HelloResponse>("/xx"); it takes 2100 ms
对我来说,从 ServiceStack 服务返回 POCO 对象列表似乎比 .NET Remoting 返回类型化数据集要慢。
T 在这种情况下看起来像这样(它有很多可为 null 的属性和 156 个属性的总数):
public partial class Nmbr
{
public Int32 NmbrID {get;set;}
public Int32 NmbrNmBaID {get;set;}
public Int32 NmbrNmStID {get;set;}
public Int32 NmbrNmInID {get;set;}
public String NmbrDesc {get;set;}
public Int32? SestID {get;set;}
public Int32? SestProjID {get;set;}
.....
....
我做错了什么?
为什么返回 List 比返回 DataSet 慢?
所有方法都共享从数据库获取数据的相同机制……对我来说,ServiceStack 中的反序列化似乎很慢。使用 webClient.DownloadData 下载数据比默认的 DataSet 序列化更快,但根据我的测量,将其转换为类型列表会额外增加 700 毫秒。
如果无法查看或 运行 您的代码来比较和验证性能消耗在哪里,我建议使用 JSON 等自描述格式在返回键入充满整数的 POCO,因为每一行都会重复每种类型的开销,当你大部分是数字时,这意味着大部分有效负载是 serializing/deserializing 模式而不是数据,例如:
[{"NumbrId":0,"NmbrNmBaID":0,"NmbrNmStID":0,...,etc},...]
您还应该查看和比较序列化数据的大小,以了解架构中的负载开销与原始数据相比有多少。
打电话的时候也要说清楚:
webClient.DownloadData("http://localhost:1337/hello/xx");
您只是在下载原始序列化数据,这总是比将其反序列化为类型化 POCO 更快。您还可以使用 ServiceStack's .NET Service Clients 下载原始数据:
var bytes = restClient.Get<byte[]>("http://localhost:1337/hello/xx");
因此您可以比较从 ServiceClient 与 WebClient 下载内容的性能。
考虑使用最佳数据格式
对于像这样的大型 Tabular/numerical 数据集,考虑使用像 Protocol Buffers or Message Pack 这样的 ServiceStack 的更优化的二进制格式,这将受益匪浅,因为它们不需要在每一行中重复模式。对于基于文本的格式,出于同样的原因,即使 CSV 也更适合传输表格数据。
您还可以通过使用 Custom Serialization with Structs 提高 ServiceStack 的 JSON 数据集序列化程序的性能,这也可以节省重复架构的开销。
我要从服务返回一个包含 6100 行和 156 列的数据表。
When returning it over .NET remoting it takes 1800 ms.
When returning it over .NET remoting with optimized DataSet serialization, it takes 1350 ms.
When just downloading a List<T> from ServiceStack (selfhosted) like this:
webClient.DownloadData("http://localhost:1337/hello/xx"); it takes 1400 ms
when returning the same list as really typed list - List<T>
var restClient = new JsonServiceClient("http://localhost:1337/hello");
all = restClient.Get<HelloResponse>("/xx"); it takes 2100 ms
对我来说,从 ServiceStack 服务返回 POCO 对象列表似乎比 .NET Remoting 返回类型化数据集要慢。
T 在这种情况下看起来像这样(它有很多可为 null 的属性和 156 个属性的总数):
public partial class Nmbr
{
public Int32 NmbrID {get;set;}
public Int32 NmbrNmBaID {get;set;}
public Int32 NmbrNmStID {get;set;}
public Int32 NmbrNmInID {get;set;}
public String NmbrDesc {get;set;}
public Int32? SestID {get;set;}
public Int32? SestProjID {get;set;}
..... ....
我做错了什么?
为什么返回 List 比返回 DataSet 慢?
所有方法都共享从数据库获取数据的相同机制……对我来说,ServiceStack 中的反序列化似乎很慢。使用 webClient.DownloadData 下载数据比默认的 DataSet 序列化更快,但根据我的测量,将其转换为类型列表会额外增加 700 毫秒。
如果无法查看或 运行 您的代码来比较和验证性能消耗在哪里,我建议使用 JSON 等自描述格式在返回键入充满整数的 POCO,因为每一行都会重复每种类型的开销,当你大部分是数字时,这意味着大部分有效负载是 serializing/deserializing 模式而不是数据,例如:
[{"NumbrId":0,"NmbrNmBaID":0,"NmbrNmStID":0,...,etc},...]
您还应该查看和比较序列化数据的大小,以了解架构中的负载开销与原始数据相比有多少。
打电话的时候也要说清楚:
webClient.DownloadData("http://localhost:1337/hello/xx");
您只是在下载原始序列化数据,这总是比将其反序列化为类型化 POCO 更快。您还可以使用 ServiceStack's .NET Service Clients 下载原始数据:
var bytes = restClient.Get<byte[]>("http://localhost:1337/hello/xx");
因此您可以比较从 ServiceClient 与 WebClient 下载内容的性能。
考虑使用最佳数据格式
对于像这样的大型 Tabular/numerical 数据集,考虑使用像 Protocol Buffers or Message Pack 这样的 ServiceStack 的更优化的二进制格式,这将受益匪浅,因为它们不需要在每一行中重复模式。对于基于文本的格式,出于同样的原因,即使 CSV 也更适合传输表格数据。
您还可以通过使用 Custom Serialization with Structs 提高 ServiceStack 的 JSON 数据集序列化程序的性能,这也可以节省重复架构的开销。