1

我创建模型来模拟复杂系统。当“代理”在系统中流动时,我会跟踪各种特征。目前,我的方法是使用多维数组。例如,我每年每个月都会报告我的代理的当前状态。我还需要跟踪这些代理的属性。所以,我使用多维数组,如下:

int[][][][][] reporting = new int[NUM_YEARS][12][NUM_POSSIBLE_SIZES][NUM_POSSIBLE_EXPERIENCES][MAX_AGE]; 

for (Agent a : agents){
    reporting[currentYear][currentMonth][a.size][a.experience][a.age] ++;

    //Size, experience, and age are integers
}

在模拟结束时,我将所有值输出到外部文件。

我的问题是这样的:

这些数组具有高度的多维性(例如,我添加了宽度、numOwners、价格、重量、高度等)。我喜欢它提供的特殊性,但是因为 Java 在我创建报告结构时会初始化所有这些整数。

在上一篇文章中,我了解到最好在数组的前面创建具有较小范围的段,例如:

int[][] reporting = new int[2][20];

好于

int[][] reporting = new int[20][2];

但是,即使进行了这种优化,我有时也会用完堆空间。我发现我通常只使用可用插槽的 1-2%!关于节省空间但为我的报告保持相同细分深度的任何提示?

我考虑过让我的写入缓冲区保持打开状态,但这似乎并不明智;我通常有五个左右的这些多维报告结构,所以我必须保持五个 BufferedWriters 处于打开状态。

谢谢!

4

1 回答 1

2

此处概述了一种可能的解决方案。该解决方案假定只有极少数可能的维度被实现,并且绝大多数是不可能的或没有意义的。

  • 使用流行的、免费提供的 java RDBMS 创建内存表

  • 表的主键应该是一个复合键,其中包含构成数组索引的所有条件。

  • 处理代理时,在表中搜索满足所有条件的记录。

  • 如果找到记录,则修改其数据。

  • 如果没有找到记录,则在表中输入一条新记录,以新条件作为主键。

  • 处理完所有代理后,您就可以在内存中获得相当紧凑、索引、可搜索的数据分析表示。

这种解决方案具有一定的优势。如果可能的维数相对于可用内存仍然很大,则可以使表基于磁盘。这使您能够以性能为代价获得非常大的数据集,否则这些数据集对于内存缓存数据结构是不可能的。另一个优点是,由于该表是由 RDBMS 引擎维护的,因此您可以使用非常强大的查询系统对其进行搜索。您基本上可以免费获得额外的多功能性。

此解决方案的主要缺点是它需要 JDBC 或某些实体映射框架,因此可能需要您学习新的 API。另一个缺点是,虽然内存表相对较快,但这种解决方案仍然比依赖于原始内存数据结构的解决方案慢。

有几个 RDBMS 选项。我是 HSQLDB ( http://www.hsqldb.org ) 的粉丝,目前版本为 2.3.0。它支持缓存表和内存表,成熟,内存占用小,可以在独立模式下使用(从而使其几乎无需管理)。其他用于 Java 的免费 RDBMS 引擎包括 Apache 的 Derby 和 SQLite,它们可以通过单独的 JDBC 驱动程序在 Java 中使用。还可以使用任意数量的库,无论是开源的还是商业的,它们为 JDBC 数据集提供复杂的、可定制的和强大的报告(例如来自 Jaspersoft 的 iReport)。

于 2013-09-12T17:52:15.513 回答