【发布时间】:2017-01-23 21:49:56
【问题描述】:
为了简单起见,我将一个非常大的 2D 空间映射到一个简单的位数组(实际上它大约有 200k 个成员)。
现在假设我运行了一个小算法,它在给定中心点和半径的情况下绘制1s 的“圆”。
这是一个例子,在左侧画了一个圆,在下一次计算中,它的中心向上移动了 1。
0000000 0001000
0001000 0011100
0011100 -> 0011100
0011100 0001000
0001000 0000000
0000000 0000000
现在我有很多层这些地图,在我计算它们之后,我需要“展平”它们(有点像 Photoshop 混合图层选项) - 目前我每次都在整个数组上迭代并组合整个数组- 尽管其中 95% 不会真正改变。
伪代码
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
int index = x + y * width
result[index] = layer1[index] * layer2[index]
这是非常低效的,我需要提高我的表现。
更新:我们最终做了什么
稀疏矩阵正是我们需要的,我们最终使用了最适合我们使用的键字典(DOK)(动态构建每一层并“混合"他们在一起)。
我们想出的解决方案是使用 3 个数组:
- 浮点数组,大小为我们可能拥有的最大成员数(值)
- 位数组(大小相同),标记值数组中哪个成员有效
- int 数组(大小相同),保存值数组中使用的索引(以便稍后对其进行迭代)+ 增量 int,用作指向索引数组中成员数量的指针
由于我们的需求严重依赖内存使用和 CPU,我们将每个稀疏矩阵包装在双缓冲区形式中,以免每次混合都生成新数组。
最终,这个解决方案在 CPU 方面为我们提供了大约 x15-x20 更好的结果(比我们之前天真的蛮力方法),在内存方面我们将 RAM 使用率降低了大约 98%。
【问题讨论】:
标签: arrays algorithm multidimensional-array