如何在许多元素始终为 0 的数组中节省内存?
How to save memory in an array of which many elements are always 0?
我在 C 中有一个 2 张量,它看起来像:
int n =4;
int l =5;
int p =6;
int q=2;
然后我初始化T的每个元素
//loop over each of the above indices
T[n][l][p][q]=...
然而,其中许多是零,并且存在对称性,例如。
T[4][3][2][1]=-T[3][4][2][1]
- 如何在 T 的零元素上节省内存?理想情况下,我想在这些位置放置类似
NULL
的内容,以便它们使用 0 而不是 8 个字节。此外,稍后在计算中我可以通过检查它们是否等于 NULL
来检查它们是否为零
- 如何使用多余的内存在 T 中隐含地包含这些对称性?
编辑:对称性也许可以通过不同的实现来修复。但是零呢?有什么实现不让它们浪费内存吗?
您不能通过写入的值影响任何变量的大小。
如果你想节省内存,你不仅不能使用它,你也不能定义一个使用它的变量。
如果你没有定义一个变量,那么你就永远不要使用它。
那你就省内存了。
这当然是显而易见的。
现在,如何将其应用于您的问题。
请允许我简化一下,一方面是因为您没有提供足够的信息和解释,至少没有让我了解每个细节。另一方面,为了保持解释简单。
所以我希望我为你解决下面的问题就足够了,我认为这是你问题的小兄弟。
我在 C 中有一个大数组(不是很大,假设有 N 个条目,N==20)。
但由于特殊原因,我永远不需要实际读写任何偶数索引,它们应该像包含 0 一样运行,但我想节省它们使用的内存。
所以实际上我只想使用 M 个条目,其中 M*2==N.
所以不用
int Array[N]; /* all the theoretical elements */
我定义
int Array[M]; /* only the actually used elements */
当然,我无法访问任何不需要的元素,而且实际上也没有必要。
但是对于我的程序的逻辑,我希望能够像我可以访问它们一样进行编程,但要确保它们始终只读取 0 并忽略任何写入值。
所以我所做的是包装对数组的所有访问。
int GetArray(int index)
{
if (index & 1)
{
/* odd, I need to really access the array,
but at a calculated index */
return Array[index/2];
} else
{
/* even, always 0 */
return 0;
}
}
void SetArray(int index, int value)
{
if (index & 1)
{
/* odd, I need to really access the array,
but at a calculated index */ */
Array[index/2] = value;
} else
{
/* even, no need to store anything, stays always "0" */
}
}
所以我可以读写,就好像数组是两倍大一样,但保证永远不会使用伪造的元素。
并将索引映射为
actualindex = wantindex / 2
我确保我不会访问超出实际存在的数组的大小。
现在将这个概念移植到您所描述的更复杂的设置中是您的工作。你知道所有的细节,你可以测试是否一切正常。
我建议通过检查结果索引来扩展 GetArray() 和 SetArray(),以确保它永远不会超出实际数组。
您还可以添加各种自我检查以验证是否满足您的所有规则和期望。
我在 C 中有一个 2 张量,它看起来像:
int n =4;
int l =5;
int p =6;
int q=2;
然后我初始化T的每个元素
//loop over each of the above indices
T[n][l][p][q]=...
然而,其中许多是零,并且存在对称性,例如。
T[4][3][2][1]=-T[3][4][2][1]
- 如何在 T 的零元素上节省内存?理想情况下,我想在这些位置放置类似
NULL
的内容,以便它们使用 0 而不是 8 个字节。此外,稍后在计算中我可以通过检查它们是否等于NULL
来检查它们是否为零
- 如何使用多余的内存在 T 中隐含地包含这些对称性?
编辑:对称性也许可以通过不同的实现来修复。但是零呢?有什么实现不让它们浪费内存吗?
您不能通过写入的值影响任何变量的大小。
如果你想节省内存,你不仅不能使用它,你也不能定义一个使用它的变量。
如果你没有定义一个变量,那么你就永远不要使用它。
那你就省内存了。
这当然是显而易见的。
现在,如何将其应用于您的问题。
请允许我简化一下,一方面是因为您没有提供足够的信息和解释,至少没有让我了解每个细节。另一方面,为了保持解释简单。
所以我希望我为你解决下面的问题就足够了,我认为这是你问题的小兄弟。
我在 C 中有一个大数组(不是很大,假设有 N 个条目,N==20)。
但由于特殊原因,我永远不需要实际读写任何偶数索引,它们应该像包含 0 一样运行,但我想节省它们使用的内存。
所以实际上我只想使用 M 个条目,其中 M*2==N.
所以不用
int Array[N]; /* all the theoretical elements */
我定义
int Array[M]; /* only the actually used elements */
当然,我无法访问任何不需要的元素,而且实际上也没有必要。
但是对于我的程序的逻辑,我希望能够像我可以访问它们一样进行编程,但要确保它们始终只读取 0 并忽略任何写入值。
所以我所做的是包装对数组的所有访问。
int GetArray(int index)
{
if (index & 1)
{
/* odd, I need to really access the array,
but at a calculated index */
return Array[index/2];
} else
{
/* even, always 0 */
return 0;
}
}
void SetArray(int index, int value)
{
if (index & 1)
{
/* odd, I need to really access the array,
but at a calculated index */ */
Array[index/2] = value;
} else
{
/* even, no need to store anything, stays always "0" */
}
}
所以我可以读写,就好像数组是两倍大一样,但保证永远不会使用伪造的元素。
并将索引映射为
actualindex = wantindex / 2
我确保我不会访问超出实际存在的数组的大小。
现在将这个概念移植到您所描述的更复杂的设置中是您的工作。你知道所有的细节,你可以测试是否一切正常。
我建议通过检查结果索引来扩展 GetArray() 和 SetArray(),以确保它永远不会超出实际数组。
您还可以添加各种自我检查以验证是否满足您的所有规则和期望。