5

我有一个 WCF 服务,它执行搜索并向客户端返回一个相当复杂的对象列表。这是一个 EAV 系统,因此返回的每个实体都有一个附加值列表,其大小取决于实体蓝图。

在我的测试搜索中,我已经通过记录确认,几乎在每种情况下,实际搜索都需要不到一秒钟的时间才能完成。在将响应返回给客户端之前,我做的最后一件事是记录处理已完成。

不幸的是,客户在我完成后 15-20 秒后才收到响应。总响应大小约为 250kb,非常小。这正在通过 LAN 传输,我尝试禁用防火墙和防病毒软件以确保两者都不会干扰。

然而,我注意到,如果响应非常小,例如通过删除附加到每个实体的字段,响应会更快地通过。我还尝试单步执行服务的本地托管 (IIS) 副本,在通过最终return语句后,仍然需要 15 秒才能到达本地客户端应用程序。

我正在使用 basicHttpBinding,因为 .Net 和 PHP 客户端都将使用该服务。

那么,任何人都可以提出一种我可以确认情况确实如此的方法吗?以及如何解决极其缓慢的序列化时间?

编辑:

为了澄清,我用 [DataContract] 属性标记了每个类,用 [DataMember] 标记了每个属性——当我返回数据时,WCF 正在处理序列化。在这种情况下,它是一个实体类型的列表(一个包含值列表的自定义类。

编辑2:

我测试了 DataContractSerializer 的速度,将 65 个返回实体的列表写入一个简单的内存流大约需要 15 秒。这看起来很荒谬,我不确定是什么改变了让它变得如此缓慢。

4

2 回答 2

5

我已经想通了,这很尴尬。

在测试 DataContractSerializer 的速度时,我使用了从搜索中返回的 65 种产品的列表。我决定将所有产品(大约 600 个)加载到数据库中,然后将它们序列化到内存中,但遇到了一些内存不足的异常,因此开始将结果写入文本文件。

原来文本文件是 1.5GB,大约是整个数据库大小的 3 倍。序列化耗时 17 秒。所以实际上,它做得非常好。发生的事情是每个产品都可以有一个附加实体列表,并且这些实体也被加载了。因为它们是序列化的,所以这些实体是重复的,它们在数据库中只存在一次。

除了删除大量客户不需要的元数据外,我还设法将 50 种产品(原本是 194MB)的列表缩小到只有 3MB。(更新:这个周末我把 1.5GB 的列表降到了 66MB)。

这个故事的主旨?倾听社区。其他人都告诉我 DataContractSerializer 有多快,所以当我觉得它很慢时,我应该责怪自己而不是 DataContractSerializer。

更新:

我花了一些时间试图弄清楚为什么这是一个突然的问题。答案在于 EAV 系统的本质——附加到任何实体的数据列表是动态的。我最初只是在请求单个实体时才加载字段数据 - 为了速度,多个实体只加载了最低限度。在我实现缓存之后,我将其更改为加载所有字段数据,但由于复杂的数据模型和大量实体,我没有预料到这会对数据量产生多大影响。真的,我不应该对我请求的数据量做出任何假设。

于 2013-09-06T17:16:30.483 回答
0

你必须使用DataContractSerializer吗?我发现发送大量数据时DataContractSerializer非常慢,性能损失不是在序列化时而是在反序列化时。

我们切换到二进制序列化,它更快,但它可能与您的 PHP 客户端不兼容。您可以编写一个可由客户端重用的组件,为您处理反序列化,但您将为所有非 .net 客户端点击它。

于 2013-09-06T15:21:35.150 回答