当前位置: 首页 > 知识库问答 >
问题:

如何在C中压缩或优化大型静态稀疏阵列[duplicate]

周浩博
2023-03-14
/* The following codes are compiled into library(test.a) */
typedef struct {
    short x[5];
} weight_t;

typedef struct {
    weight_t wgt;
    char *ptr;
} myarray_t;

/* huge static array and 70% of entries are empty/zero */
static myarray_t array1[] ={
{ { 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, }, 0 }, /* 0000 */
{ { 0x0103, 0x0103, 0x0103, 0x0103, 0x0103, }, 0 }, /* 0001 */
{ { 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, }, 0 }, /* 0002 */
{ { 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, }, 0 }, /* 0003 */

{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, 0 }, /* 3134c */
{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, 0 }, /* 3134d */
......
......
.....

} /* more than one millon entries */

由于array1包含100多万个条目(即使其中70%是空/零条目),库文件(test.a)的大小相当大。

我知道使用哈希表只包含非空条目可以减少array1的大小,但这是否可以在不更改array1的情况下压缩或优化库文件(test.a)的大小?

由于array1已被其他库引用,因此对array1进行改造以使用其他实现可能不是解决我当前情况的方法。

这是对C语言中大型稀疏数组的压缩或大小优化的后续,基本上是在要求同样的事情,即在不改变内存数据结构的情况下保存文件大小。这一个被标记为编译器优化,另一个没有。(编者按:我不认为这会使它们之间的差异足以成为非重复的;除非我们澄清这个问题的区别,否则就结束这个问题。)

共有1个答案

仲孙默
2023-03-14

一个明显的大小优化是去掉结构填充。您可以在2x5字节数组和指针之间填充,和/或在结构末尾填充。您可能使用2x5 4=14字节或2x5 8=18字节的实际数据。如果4或8字节对齐,两者都不合适。

因此,删除结构:

static short array1 [5*n] = { ... };
static char* ptr [n] = { ... };

这将删除当前低效结构中存在的所有填充。您将为每个项目节省大约2-6个字节,这意味着一百万个项目浪费了大约2-6兆字节的空间。

gccx86_64Linux示例:

#include <stdio.h>

#define n 1000000

int main()
{
    typedef struct {
        short x[5];
    } weight_t;

    typedef struct {
        weight_t wgt;
        char *ptr;
    } myarray_t;

    static myarray_t array1[n];
    printf("%zu\n", sizeof array1);

    static short array2 [5*n];
    static char* ptr [n];
    printf("%zu\n", sizeof array2 + sizeof ptr);

    return 0;
}

输出:

24000000
18000000

更改在这个特定系统上节省了600万字节。如果由于某些向后兼容性原因而被当前结构所困扰,请考虑使用一些包装宏来模拟使用SoW数组时的结构类似的访问。

 类似资料:
  • 由于array1包含100多万个条目(即使其中70%是空/零条目),库文件(test.a)的大小相当大。 我知道使用哈希表只包含非空条目可以减少array1的大小,但是有没有办法在不更改的情况下压缩或优化库文件(test.a)的大小? 在struct中,在其他库中有很多地方可以访问的值,要更改当前的静态数组实现可能需要付出巨大的努力。

  • 我正在跟踪粒子到三维晶格中。每个晶格元素都有一个对应于展开的3D数组的索引 我对从S1单元到S2单元的过渡感兴趣。由此产生的过渡矩阵M(S1,S2)人口稀少,因为粒子只能在细胞附近到达。不幸的是,使用几何上接近的展开3D阵列单元的索引可能会在索引上有很大差异。例如,位于彼此顶部(例如z和z 1处)的单元格的索引将按宽度*深度移动。因此,如果我尝试累积得到的2D矩阵M(S1,S2),S1和S2将非常

  • 本文向大家介绍C++ 实现稀疏矩阵的压缩存储的实例,包括了C++ 实现稀疏矩阵的压缩存储的实例的使用技巧和注意事项,需要的朋友参考一下 C++ 实现稀疏矩阵的压缩存储的实例 稀疏矩阵:M*N的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律。  稀疏矩阵的压缩存储:压缩存储值存储极少数的有效数据。使用{row,col,value}三元组存储每一个有效数据,三元组按原矩阵中的位置

  • 我正在实现一个稀疏矩阵类,使用映射向量来存储数据(映射表示矩阵的一行,其中键是列的索引,值是该位置的maitrix的值)我已经编写了计算行列式的函数,但我不知道是否有一种方法可以计算这种节省的时间(因为矩阵是稀疏的,大多数值为零)在这里我的实现: 这是类接口 我计算行列式的方式是什么?假设运算符()以这种方式重载 提前感谢您的帮助

  • 本文向大家介绍C++ 数据结构之对称矩阵及稀疏矩阵的压缩存储,包括了C++ 数据结构之对称矩阵及稀疏矩阵的压缩存储的使用技巧和注意事项,需要的朋友参考一下 对称矩阵及稀疏矩阵的压缩存储 1.稀疏矩阵  对于那些零元素数目远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称为稀疏矩阵(sparse)。   人们无法给出稀疏矩阵的确切定义,一般都只是凭个人的直觉来理解这个概念,即矩阵中非零元素的个

  • 2.5.1 介绍 (密集) 矩阵是: 数据对象 存储二维值数组的数据结构 重要特征: 一次分配所有项目的内存 通常是一个连续组块,想一想Numpy数组 快速访问个项目(*) 2.5.1.1 为什么有稀疏矩阵? 内存,增长是n**2 小例子(双精度矩阵): In [2]: import numpy as np import matplotlib.pyplot as plt x = np.li