如何有效地将二维字节数组复制到更大的2D数组中?

时间:2010-06-29 06:10:55

标签: arrays performance haskell

我有一个名为Patch的结构,它代表一个2D数组数据。

newtype Size = (Int, Int)
data Patch = Patch Size Strict.ByteString

我想从一组较小的Pat和它们指定的位置构建一个更大的Patch。 (补丁不重叠。)函数如下所示:

newtype Position = (Int, Int)

combinePatches :: [(Position, Patch)] -> Patch
combinePatches plan = undefined

我看到两个子问题。首先,我必须定义一个函数将2D数组副本转换为一组1D数组副本。其次,我必须从所有这些副本中构建最终的补丁。

请注意,最终的Patch将是大约4 MB的数据。这就是为什么我想避免一种天真的方法。

我非常有信心我可以做到这一点非常低效,但我想就如何在Haskell中有效地操纵大型2D数组提出一些建议。我一直在看“矢量”库,但我以前从未使用它。

感谢您的时间。

1 个答案:

答案 0 :(得分:2)

如果规范实际上只是从一组先前的Patch和它们的位置一次性创建一个新Patch,那么这是一个简单的单遍算法。从概念上讲,我认为它是两个步骤 - 首先,将现有的补丁组合成一个数据结构,并对任何给定位置进行合理的查找。接下来,通过查询复合结构来懒惰地编写新结构。这应该大致为O(n log(m)) - n是您正在编写的新数组的大小,m是补丁的数量。

如果使用Vector库而不是原始ByteString,这在概念上要简单得多。但是,如果您只使用Data.Array.Unboxed,它仍然更简单。如果你需要可以与C互操作的数组,那么请改用Data.Array.Storable。

如果你放弃纯度,至少在本地,并使用ST阵列,你应该能够在O(n)时间内完成这项工作。当然,常数因素仍然比使用一次快速复制内存块更糟糕,但是没有办法让代码看不到低级别。