【问题标题】:Efficient mapping of 2d array二维数组的高效映射
【发布时间】:2021-07-15 11:06:19
【问题描述】:

这听起来像是一个非常基本的问题,但我还没有找到令人满意的答案。

我需要将一个值数组映射到一个二维索引数组,大约每秒 60 次。为了减少工作量,我想找到最有效的方法。 目前我在做什么(为了这个例子):

int[] COLOR_MAP = new int[] { 0xFFFFFF, 0xD3D3D3, 0xA9A9A9, 0x000000 };
int[][] indices = new int[][] {
        {0, 1, 2, 3},
        {3, 2, 1, 0},
        {2, 1, 3, 3},
        {1, 1, 2, 2},
};
int[][] colors = new int[4][4];

for (int y = 0; y < 4; ++y)
        for (int x = 0; x < 4; ++x)
                colors[y][x] = COLOR_MAP[indices[y][x]];

地图是否有等价物或“类似scala”的东西?摆脱嵌套循环的最有效方法是什么?

【问题讨论】:

  • “我需要映射一组值……大约每秒 60 次。”哪个数组每秒更改 60 次,COLOR_MAP 还是索引?
  • 索引。嵌套循环以 60Hz 的频率调用,以在给定索引数组和颜色图的情况下创建缓冲图像
  • 指数如何变化?每帧是否低于 10%?换句话说,您能否创建一个索引更改的稀疏列表并仅更新框架中实际更改的颜色值?
  • 很可能每个像素都会发生变化,甚至是轻微的变化
  • 那么@Peter Walser 的回答可能是你能做的最好的。只需确保您的索引和颜色矩阵大小是 2 的幂。

标签: java performance optimization


【解决方案1】:

x=0..3 和 y=0..3 上的嵌套循环可以重写为 i=0..15 的循环。 然后将变量 x 和 y 计算为:

  • x = i % 4
  • y = i / 4

由于数组维度是 2 的幂,这简化了更快的操作:

  • x = i &amp; 0b11
  • y = i &gt;&gt; 2

理想情况下,索引也是一维数组。这看起来像这样:

int[] COLOR_MAP = new int[]{0xFFFFFF, 0xD3D3D3, 0xA9A9A9, 0x000000};
int[] indices = new int[]{
        0, 1, 2, 3,
        3, 2, 1, 0,
        2, 1, 3, 3,
        1, 1, 2, 2,
};
int[][] colors = new int[4][4];

for (int i = 0; i < 16; i++) {
    colors[i >> 2][i & 0b11] = COLOR_MAP[indices[i]];
}

【讨论】:

  • JIT 应用的优化之一是强度降低。因此,它将用具有相同效果的更便宜的操作代替昂贵的操作。因此,运行微基准测试并检查它是否真的有所作为可能是一件好事。
猜你喜欢
  • 2016-11-22
  • 2019-09-21
  • 2018-06-10
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多