我有一个执行搜索的WCF服务,并向客户端返回一个相当复杂的对象列表。这是一个EAV系统,因此返回的每个实体都有一个附加值列表,其大小根据实体蓝图而变化。
在我的测试搜索中,我已通过记录确认实际搜索在几乎每种情况下都需要一秒钟才能完成。在将响应返回给客户端之前,我做的最后一件事就是处理完成的日志。
不幸的是,客户端在我完成它之后15-20秒才收到响应。总响应大小约为250kb,因此非常小。这是通过局域网传输的,我尝试禁用防火墙和防病毒软件以确保它们都没有干扰。
然而,我注意到,如果响应相当小,例如通过删除附加到每个实体的字段,响应速度会快得多。我还试图单步执行本地托管(IIS)服务的副本,并在传递最后的return
语句后,还需要15秒才能到达本地客户端应用程序。
我正在使用basicHttpBinding,因为.Net和PHP客户端都会使用该服务。
现在,有人可以建议我确认这种情况确实如此吗?我怎么能解决速度慢的序列化时间?
修改
为了澄清,我已经使用[DataContract]属性标记了每个类,并且每个属性都使用[DataMember] - WCF在返回数据时处理序列化。在这种情况下,它是一个Entity类型的List(一个包含值列表的自定义类。
编辑2:
我已经测试了DataContractSerializer的速度,并且花了大约15秒将一个包含65个返回实体的列表写入一个简单的内存流。这看起来很荒谬,而且我不确定是什么改变了让它如此痛苦地缓慢。
答案 0 :(得分:4)
我已经弄清楚了,这很令人尴尬。
在测试DataContractSerializer的速度的同时,我使用了从搜索中返回的65种产品的列表。我决定在数据库中加载所有产品(大约600个),然后将它们序列化到内存中,但是会出现一些内存不足的异常,所以开始将结果写入文本文件。
事实证明,文本文件是1.5GB,大约是整个数据库大小的3倍。序列化需要17秒。实际上,它做得非常好。发生的事情是每个产品都可能有一个附加实体列表,并且这些实体也被加载。因为它们是序列化的,所以这些实体是重复的,它们只存在于数据库中一次。
除了剥离客户端不需要的大量元数据外,我还设法获得了50个产品(已经是194MB)的列表,只有3MB。 (更新:本周末我将1.5GB列表降至66MB)。
故事的寓意?听取社区的意见。其他人告诉我DataContractSerializer的速度有多快,所以当我看起来很慢的时候,我应该责怪自己而不是DataContractSerializer。
<强>更新强>
我花了一些时间试图弄清楚为什么这是一个突然的问题。答案在于EAV系统的性质 - 附加到任何实体的数据列表是动态的。我原本只在请求个人实体时加载了现场数据 - 为了速度,多个实体仅加载了最小值。在我实现缓存之后,我将其更改为加载所有字段数据,但是由于复杂的数据模型和大量实体,没有预料到这对数据量会产生多大的差异。真的,我不应该假设我要求的数据量。
答案 1 :(得分:0)
您必须使用DataContractSerializer
吗?我发现DataContractSerializer在发送大量数据时速度非常慢,在序列化时但在反序列化时不会出现性能损失。
我们切换到二进制序列化,速度要快得多,但它可能与PHP客户端不兼容。您可以编写一个可以由客户端重用的组件,为您处理反序列化,但是您将为所有非.net客户端点击此组件。