gpt4 book ai didi

c# - 在 C#/.NEt 中,动态类型占用的空间是否比对象少?

转载 作者:IT王子 更新时间:2023-10-28 23:32:57 27 4
gpt4 key购买 nike

我有一个控制台应用程序,允许用户指定要处理的变量。这些变量有三种形式:string、double 和 long(double 和 long 是迄今为止最常用的类型)。用户可以以任何顺序指定他们喜欢的任何变量,因此我的系统必须能够处理它。为此,在我的应用程序中,我一直将它们存储为对象,然后根据需要进行转换/取消转换。例如:

public class UnitResponse
{
public object Value { get; set; }
}

我的理解是盒装对象比标准值类型占用更多的内存(大约 12 个字节)。

我的问题是:使用 dynamic 关键字存储这些值会更有效吗?它可能会解决装箱/拆箱问题,如果它更有效,这将如何影响性能?

编辑

在最坏的情况下,为了提供一些上下文并防止“您确定您使用足够的 RAM 来担心这个”,我需要担心 420,000,000 个数据点(60 个变量 * 7,000,000 条记录)。这是我保留的关于每个变量的一堆其他数据(包括一些 bool 值等)的补充。所以减少内存确实会产生巨大的影响。

最佳答案

好的,所以这里的真正问题是“我有一个非常庞大的数据集存储在内存中,我如何优化它在时间和内存空间上的性能?”

几个想法:

  • 你对拳击的仇恨和恐惧是绝对正确的。拳击的成本很高。首先,是的,装箱的对象会占用额外的内存。其次,装箱对象存储在堆中,而不是堆栈或寄存器中。第三,它们是垃圾收集的;这些对象中的每一个都必须在 GC 时进行查询,以查看它是否包含对另一个对象的引用,而它永远不会,这在 GC 线程上占用了大量时间。你几乎肯定需要做一些事情来避免拳击。

动态不是吗?这是拳击加上一大堆其他开销。 (与其他动态调度系统相比,C# 的动态速度非常快,但从绝对意义上来说它并不快或小)。

这很恶心,但您可以考虑使用一个结构,其布局在各个字段之间共享内存 - 就像 C 中的联合。这样做真的很恶心并且根本不安全 但它可以在这样的情况下提供帮助。在网络上搜索“StructLayoutAttribute”;你会找到教程。

  • 真的是长、 double 还是字符串?不能是 int、float 或 string?数据是否真的超过了数十亿的数量级或精确到小数点后 15 位?对于 99% 的情况,int 和 float 不能完成这项工作吗?它们只有一半大小。

通常我不建议使用 float 而不是 double,因为它是一种虚假的经济;当他们有一个数字时,人们通常会以这种方式节约,就像节省四个字节会有所作为。 4200 万个 float 和 4200 万个 double 之间的差异是相当大的。

  • 您可以利用的数据中是否存在规律性?例如,假设在您的 4200 万条记录中,每个长整数只有 100000 个实际值,每个 double 只有 100000 个值,每个字符串只有 100000 个值。在这种情况下,您为 long、double 和字符串创建某种类型的索引存储,然后每条记录都得到一个整数,其中低位是索引,前两位表示从哪个存储中取出它。现在您有 4200 万条记录,每条记录都包含一个 int,并且这些值以某种非常紧凑的形式存储在其他地方。

  • 将 bool 值存储为字节中的位;编写属性来进行位移以将它们取出。这样可以节省几个字节。

  • 记住,内存实际上是磁盘空间; RAM 只是它上面的一个方便的缓存。如果数据集太大而无法保存在 RAM 中,那么 something 会将其分页回磁盘并稍后再读回;那可能是您,也可能是操作系统。您可能比操作系统更了解您的数据位置。您可以以某种方便的可分页形式(如 b 树)将数据写入磁盘,并更有效地将数据保存在磁盘上,并仅在需要时才将其放入内存。

关于c# - 在 C#/.NEt 中,动态类型占用的空间是否比对象少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4823213/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com