8

我目前正在处理的项目有很多被序列化的对象,以便获得现有对象的深层副本。这工作正常,直到我们在运行时有多个调用,在某些情况下,我们在组件之间有 100、200 甚至 1000 个调用,这就是我们遇到性能问题的地方。

复制这些对象被克隆的历史原因是,在不同功能下处理相同对象的两个不同组件不应相互更改,例如 Swing UI 中的更改不应更改后端中的对象值,直到按下保存或同步按钮。

我们有相当大的代码库,我想如果我基于反射编写克隆,它会比序列化更快,但由于我们复杂的对象层次结构或其他原因,这种方法甚至更慢。

我也尝试过使用 CloneUtils (sourceforge project),它也比较慢(我们根本没有使用 Hibernate)。Spring BeanUtils 不是一个选项(我从文档中假设它只使用 bean,即自省,如果我使用它,如果使用非标准访问器公开任何字段,我们将无法复制这些)。

有谁知道,提高性能,同时仍在处理不同的副本。如果我们提供自己的复制方法而不是序列化,我们有一个选项可以加快速度,但是每次更新这些方法都有缺点,如果我们忘记了我们可能会失去功能。

4

4 回答 4

1

您可以通过动态类生成来避免反射,例如,使用cglib。对于您使用的每个类,您将生成一个“克隆类”,其中包含复制所需的代码。这将使反射变得不必要,前提是所有字段至少是包私有的,并且您将复印机类放在同一个包中。您也需要一个默认的 ctor 并且没有最终字段。

在这里,序列化有一个优势,因为它使用sun.misc.Unsafe.

在每个类中实现一个deepClone方法也是一种选择。它甚至可以与克隆人级的想法相结合。

于 2011-02-09T15:35:59.920 回答
0

您所描述的是一种管理可变状态的霰弹枪方法。尝试使克隆更快只会给您带来有限的改进(例如达到一个数量级)。此外,如何克隆套接字、流或数据库连接?

您真正需要的是通过适当的命令/查询分离重构您的应用程序。通过这种方式,您将知道您在哪里更改您的对象以及您不在哪里。如果不确定,您可以使用单元测试来验证这一点。

有许多技术可以帮助您 - 您可以将某些对象更改为不可变(因此您可以自然地共享它们,在突变时创建新副本);您可以使可变对象实现只读接口并使用 GUI 中的 RO 视图等。

于 2011-02-09T15:36:42.143 回答
0

只需提示您如何在这种情况下提高性能:如果您还没有使用原型模式,请使用它。您可能会获得一些性能

于 2011-02-09T15:04:48.053 回答
0

我怀疑通过遵循您提到的方法,您可以做很多事情来显着提高性能。不幸的是,复制对象确实需要时间。

稍微横向思考一下,显然取决于你有多少内存以及读写器的比例(特别是如果你每次写都有很多读者),那么创建一个副本缓存怎么样?

于 2011-02-09T15:06:51.710 回答