【问题标题】:Array serialization performance issue数组序列化性能问题
【发布时间】:2010-10-01 10:17:53
【问题描述】:

在我的 Windows Mobile (.NET Compact Framework) 应用程序中,我使用一个大数组来存储应用程序的主要数据。这是一个可能包含数百个对象的数据集。每个对象有大约 10 个左右的属性和两个自身的数组,每个数组有大约 25 个其他对象,每个对象有大约 5 个属性。

为了在移动设备上保存这个数组,我只是序列化了整个数组。这在大多数情况下都很有效,而且非常非常简单。

但是,在我们的测试用例中,我们总是只使用少数对象,最多大约 50 到 75 个。但我们的客户有一些案例,用户拥有数百个这样的对象,最多 1000 个。在这些案例中,序列化速度很慢,可能需要一分钟。

实际的问题是在保存整个数组时,大多数情况下实际上只有几个对象发生了变化。所以基本流程是这样的:

  • 从存储中加载整个数组,比如 400 个对象;
  • 更改 1 个对象的一些属性;
  • 将整个数组保存回存储器,即全部 400 个对象;
  • 更改同一对象的多个属性;
  • 再次保存
  • 更改最终属性;
  • 再次保存;
  • 与任何后续对象相同...

如果不经常进行保存,通常不会有问题,但在几个中间步骤中,数据会被保存。这是为了确保所有数据都被持久化并且不会发生数据丢失(例如当电池没电时)。

我该如何解决这个问题?

【问题讨论】:

  • 我对 Windows Mobile 并不特别熟悉,但对于“移动”而言,一般来说,与设备之间的传输是性能真正重要的地方。我会调整您的代码,以便您只发送/接收更改的数据。例如在您的示例中,一次只发送“几个属性”。 (请记住,数据传输通常会花费最终用户 $ 金钱 - 因此您希望它尽可能少)
  • 数据传输没有问题。传输速度足够快(通常使用 Wifi 或底座中的“直接”连接)。但是内部(永久)内存(闪存、SD 卡或其他任何东西)的序列化速度很慢。
  • 好的,但我认为这个问题又与修改了多少数据有关。我只会根据需要更新内部数据结构......例如更新索引“X”处的子数组以添加这 3 个项目。不要尝试将整个结构发送回设备并重新构建整个数据结构。

标签: .net arrays serialization compact-framework


【解决方案1】:

所以要明确一点,请确保我理解您的情况:

  • 您所拥有的是某种形式的序列化数组(您没有将格式声明为 XML、二进制或其他格式)作为您的数据存储?
  • 如果一个属性发生变化,你重写整个数组,即使有1000个对象有子对象?
  • 您正在写入闪存,而不仅仅是 RAM?
  • 为了完整的“保存”,您要执行几次写入操作?
  • 出于某种原因,您发现这很慢,而且数据集越大,速度就越慢?

答案其实很简单。根据您的操作方式,这完全是预期的行为。为什么要将这种机制用于数据存储,尤其是对于大型、频繁更改的项目?这是一个糟糕的设计决策的典型例子。当属性更改时,您应该只更改存储中的该属性,而序列化数组根本不适合此。

您应该使用实际的数据库引擎,无论它是 RDBMS 还是对象数据库,但这样做的方式是减少对存储介质的写入。如果您需要将数据作为数组传输到 PC/服务器,那很好 - 创建一种机制从存储中提取并将其放入数组中。

【讨论】:

  • 速度慢我并不意外,我认为这是合乎逻辑的,但我想找到一个解决方案(可能通过使用另一种方法来保存)。我保存了多次以防止数据丢失(正如我所描述的,例如,如果电池在运行时没电了)。我使用序列化是因为它很容易(只有一种方法)。 RDBMS 非常复杂。正如我所说,它是一个移动平台,所以我不能只将 MySQL 或 PostgreSQL 放在上面。感谢您批评我目前的实施,但没有对我的实际问题给出任何具体答案。
  • 如何给出具体的解决方案?实现是模棱两可的,所以我给出了一个模棱两可的“使用数据存储而不是序列化数组”的答案。 RDBMS 并不是那么复杂,特别是如果您使用 ORM,并且有一些(如 SQL Compact 和 SQLite)可在设备上使用。同样,许多对象数据库(如 db4o 和 Perst)也同样简单。我真的无法告诉您使用哪个,因为我对您的应用程序、您的经验水平或您的要求一无所知。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
相关资源
最近更新 更多