#2d-array #array #2d-grid #2d #grid #block-size #matrix

无需std block-grid

快速、缓存意识、瓦片的二维数组

4个版本

0.1.3 2022年1月5日
0.1.2 2021年5月7日
0.1.1 2021年2月1日
0.1.0 2020年11月1日

236内存管理 中排名

每月 35 次下载
2 个Crate中使用(通过 keeshond_treats

MIT 许可证

61KB
1K SLoC

block-grid

快速、缓存意识、分块的二维数组

Crate Docs License CI

block-grid 提供了一个固定大小、二维数组,具有分块内存表示。如果你经常访问附近的坐标,这将带来很大的好处,即更加缓存友好。

功能

  • 可以存储任何类型
  • 泛型编译时块大小
  • 使用 (row, col): (usize, usize) 进行索引
  • 使用 BlockBlockMut 进行块级访问
  • 从行主序和列主序数组构建
  • 内存中、行主序和按块迭代的迭代器
  • no_stdserde 支持
  • 还支持无块(即经典行主序)

示例

use block_grid::{BlockGrid, CoordsIterator, U2};

fn main() {
    let data: Vec<_> = (0..(4 * 6)).collect();

    // Construct from row-major ordered data
    let grid = BlockGrid::<usize, U2>::from_row_major(4, 6, &data).unwrap();

    // The 2D grid looks like:
    // +-----------------------+
    // |  0  1 |  2  3 |  4  5 |
    // |  6  7 |  8  9 | 10 11 |
    // |-------+-------+-------|
    // | 12 13 | 14 15 | 16 17 |
    // | 18 19 | 20 21 | 22 23 |
    // +-----------------------+

    // Indexing
    assert_eq!(grid[(1, 3)], 9);

    // Access raw array
    let first_five = &grid.raw()[..5];
    assert_eq!(first_five, &[0, 1, 6, 7, 2]);

    // Iterate over blocks, and access the last
    let block = grid.block_iter().last().unwrap();
    assert_eq!(block[(0, 1)], 17);

    // Iterate in row-major order
    for (i, &x) in grid.row_major_iter().enumerate() {
        assert_eq!(x, i);
    }

    // Iterate in memory order, with coordinates
    for ((row, col), &x) in grid.each_iter().coords() {
        assert_eq!(row * 6 + col, x);
    }
}

为什么

TODO:关于缓存的说明

权衡

  • 不可调整大小,并且网格维度必须是块大小的倍数。
  • 目前,仅支持正方形块和2的幂次方块大小。
  • 计算修改后的索引需要更多一点的时间。
  • 当跨越瓦片边界时,仍然会缓存未命中。
  • 不支持步长或通用子集。

变更日志

查看 CHANGELOG.md

许可证

block-grid 根据 MIT 许可证 许可。

替代方案

如果你的访问模式适合典型的行主序内存表示,你仍然可以使用 block-grid!但是,如果你真的想寻找替代方案,请查看 array2dimgrefgridtoodee。后两者支持动态调整大小。对于矩阵和线性代数,还有 nalgebra

依赖项

~165KB