0

我有 2D 水力数据,这些数据是数千兆字节的文本文件,其中包含网格中每个点的深度和速度信息,分为时间步长。每个时间步包含网格中每个点的深度/速度值。因此,您可以在每个时间步中跟踪一个点,看看它的深度/速度如何变化。我想一次读取一个时间步长的数据,计算各种东西 - 网格单元达到的最大深度、最大速度、水深超过 2 英尺的第一个时间步长的数量等。每个结果这些计算将是一个网格 - 每个点的最大深度等。

到目前为止,这听起来像是装饰器模式。但是,我不确定如何从各种计算中得到结果——每次计算都会产生不同的网格。在创建每个装饰器后,我必须保留对它的引用,以便从中提取结果,或者添加一个getResults()返回不同结果的映射的方法,等等,这两种方法听起来都不理想。

另一种选择是策略模式。每个计算都是一种不同的算法,它在时间步长(当前深度/速度)和前几轮的结果(迄今为止的最大深度、迄今为止的最大速度等)上运行。然而,这些先前的结果对于每次计算都是不同的——这意味着算法类要么成为有状态的,要么成为调用者的工作来跟踪先前的结果并将它们输入。我也不喜欢策略模式,因为循环的行为timesteps 成为调用者的责任 - 我只想给“计算器”一个迭代器(根据需要从磁盘中获取它们)并让它产生它需要的结果。

附加约束:

  • 输入很大并且从磁盘读取,因此按时间步只迭代一次是唯一实用的方法
  • 网格很大,因此应尽可能就地进行计算
4

2 回答 2

0

如果我理解你的问题是正确的,你有一个 grid_points 有很多时间步长并且每个时间步长都有深度和速度。现在有 GB 的数据。

我建议对数据进行一次传递并将解析的数据存储在 RDBMS 中。然后对此数据运行查询或存储过程。这样至少应用程序不会耗尽内存

于 2012-09-11T17:10:39.377 回答
0

首先,也许我没有很好地理解这个问题并且错过了我的回答中的重点,在这种情况下,我很抱歉占用您的时间。

乍一看,我会想到一种更类似于“策略模式”的方法,结合面向数据的基础,类似于以下伪代码:

foreach timeStamp

  readGridData

  foreach activeCalculator in activeCalculators

    useCalculatorPointerListToAccessSpecificStoredDataNeededForNewCalculation

    performCalculationOnFreshGridData

    updateUpdatableData

    presentUpdatedResultsToUser

    storeGridResultsInDataPool(OfResultBaseClassType)

    discardNoLongerNeededStoredGridResults

  next calculator
next timeStep

再次,对不起,如果这是题外话。

于 2012-09-11T17:19:45.637 回答