2

我有一大组数据(一个 250,000 X 1,000 双倍的数据立方体,大约 4 gig 文件),我想使用我以前用 Python 编写的一组 OOP 类来操作它。目前,数据集已经非常大,要读入我的机器内存,我至少必须将其分成两半,因此计算开销是一个问题。我的 OOP 类创建新对象(在这种情况下,我需要 250,000 个新对象,每个对象是一个包含 1,000 个双精度数的数组)来处理数据。为通用 OOP 语言创建对象所需的内存和计算开销是多少?在蟒蛇?在 C++ 中呢?

是的,我意识到我可以创建一个新的数组类。但是 1)我已经完成了这些类,并且 2)我将创建的每个对象放回数组中,以便以后访问。这个问题是教学问题

*更新:我想在时间、我的时间和计算机上保持高效。我不想重写我已经拥有的程序,如果我不需要的话,花时间优化代码会浪费我的时间,如果我浪费计算机时间,我也不在乎。我实际上确实有一台带有 4Gig ram 的 64 位机器。数据是一个图像,我需要对每个像素做几个过滤器。*

4

14 回答 14

3

对于过程/函数式编程语言,您会遇到类似的问题。你如何在内存中存储这么多数据?结构或数组也不起作用。

您需要采取特殊步骤来管理这种规模的数据。

顺便说一句:我不会以此作为选择 OO 语言或不选择的理由。

于 2008-12-16T20:24:58.250 回答
3

http://code.activestate.com/recipes/546530/

这是 Python 对象的近似大小。

OO 大小的“惩罚”通常被以下能力所抵消:(a)简化处理和(b)首先在内存中保留更少的东西。

没有 OO 性能开销。零。在 C++ 中,类定义经过优化,不存在了,剩下的就是 C。在 Python 中——像所有动态语言一样——动态编程环境增加了一些运行时查找。大多数情况下,这些是直接散列到字典中。它比编译器为您完成所有解析的代码要慢。然而,它仍然非常快,开销相对较低。

C 中的错误算法很容易比 Python 中的正确算法慢。

于 2008-12-16T20:48:12.727 回答
3

有点 OT:当您处理大型数据集时,享元设计模式可用于最大限度地减少开销。在不知道您的问题的详细信息的情况下,我不确定它的适用性如何,但是值得一看...

于 2008-12-16T21:15:02.250 回答
2

我认为将您的设计的任何缺点归咎于 OOP 是不公平的。就像那里的任何其他编程平台一样,OO 既可以用于良好的设计,也可以用于次优设计。这很少是编程模型本身的错。

但是要尝试回答您的问题:分配 250000 个新对象需要我知道的所有 OO 语言的一些开销,因此如果您可以通过同一实例流式传输数据,那么您可能会更好。

于 2008-12-16T20:10:28.700 回答
1

实际的 C++ OO 内存开销是每个具有虚拟方法的对象一个指针(4-8 个字节,具体取决于)。但是,正如其他答案中所提到的,动态分配的默认内存分配开销可能会明显大于此。

如果你在合理的情况下做事,那么与 1000*8 字节的双精度数组相比,这两种开销都不大。如果你真的担心分配开销,你可以编写自己的分配器——但是,首先检查它是否真的会给你带来显着的改进。

于 2008-12-16T21:24:38.957 回答
0

如果不知道数据的形状和您为包含它而设计的结构,就无法回答。

于 2008-12-16T20:06:48.753 回答
0

“开销”在很大程度上取决于您选择的平台和实现。

现在,如果您在从多个 Gb 文件中读取数百万数据时遇到内存问题,那么您将遇到算法问题,其中对象的内存消耗绝对不是最大的问题,您更关心的是如何获取、处理和存储数据。

于 2008-12-16T20:34:36.920 回答
0

就像其他海报所说的那样。我不相信对象会给您的流程带来大量开销。它将需要存储一个指向该对象的指针,但其余的“双打”将占用程序 99% 的内存。

你能把这些数据分成更小的子集吗?您要完成的任务是什么?我很想看看你需要内存中的所有数据做什么。也许你可以序列化它,或者在 haskell 中使用惰性求值之类的东西。

请发布后续信息,以便我们更好地了解您的问题域。

于 2008-12-16T20:43:57.273 回答
0

我不认为这个问题是来自 OO 的开销。

如果我们接受 C++ 作为 OO 语言,并记住 C++ 编译器是 C 的预处理器(至少在我使用 C++ 时曾经是),那么在 C++ 中完成的任何事情实际上都是在 C 中完成的。C 的开销很小。所以这将取决于图书馆。

我认为任何开销都来自解释、托管执行或内存管理。对于那些拥有工具和专业知识的人来说,很容易找出哪个最有效,C++ 还是 Python。

我看不出 C++ 会在哪里增加很多可避免的开销。我对 Python 了解不多。

于 2008-12-16T20:48:41.353 回答
0

与数据集的大小相比,250K 对象的开销可以忽略不计

我认为你走错了路;不要为此责备对象;-)

于 2008-12-16T21:03:58.450 回答
0

请定义“操纵”。如果你真的想操纵 4 场数据,为什么要立即将其全部拉入内存来操纵它?

我的意思是,谁需要 4 gig 的 RAM?:)

于 2008-12-16T21:09:31.123 回答
0

如果你必须定期处理这么大的数据集,你能不能得到一台带有大量 RAM的64 位机器?出于各种原因,我发现自己在使用相当资源匮乏的软件(在本例中为 SQL Server Analysis Services)。这类较旧的 64 位机器可能会占用大量 RAM,并配备 CPU,虽然不是最先进的,但仍然相当快。

我买了一些二手的惠普工作站,并为它们安装了几个快速 SCSI 磁盘。2007 年年中,这些配备 4 或 8GB RAM 和 5 个 10K 或 15K SCSI 磁盘的机器的购买成本在 1,500 至 2,000 英镑之间。磁盘成本是机器成本的一半,而且您可能不需要 I/O 性能,因此您可能不需要花这么多钱。 我购买的那种XW9300现在可以在 ebay 上以相当便宜的价格购买——我的这篇文章介绍了使用 ebay 以便宜的价格获得高规格 64 位盒子的各种选择。您可以在 ebay 上将这些机器的内存升级到 16 或 32GB,而价格仅为零件标价的一小部分。

于 2008-12-16T21:28:39.120 回答
0

我的一个朋友是麻省理工学院的教授,一个学生问他为什么他的图像分析程序运行这么慢。它是如何建造的?每个像素都是一个对象,并且会向它的邻居发送消息!

如果我是你,我会在一次性程序中尝试。我的怀疑是,除非您的类被非常仔细地编码,否则您会发现它会花费大量时间分配、初始化和取消分配对象,并且正如 Brian 所说,您可能能够通过一组假脱机数据重复使用的对象。

编辑:对不起。您说您正在重用对象,这很好。无论如何,当你让它运行时,你可以对其进行分析,或者(如果你是我的话)只是随机读取调用堆栈几次,这将回答关于时间去向的任何问题。

于 2008-12-16T21:29:24.093 回答
0

由于您可以将数据分成两半并对其进行操作,我假设您正在单独处理每条记录?在我看来,您需要更改解串器以一次读取一条记录,对其进行操作,然后存储结果。

基本上你需要一个字符串解析器类,它执行一个返回字符的 Peek(),知道如何跳过空格等。围绕理解你的数据格式的类包裹一个类,你应该能够让它吐出一个对象它读取文件的时间。

于 2008-12-16T21:37:35.670 回答