什么是面向对象的编程计算开销成本?

时间:2008-12-16 20:04:07

标签: python oop data-analysis

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

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

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

14 个答案:

答案 0 :(得分:3)

程序/函数编程语言也存在类似问题。你如何将这么多数据存储在内存中?结构或数组也不起作用。

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

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

答案 1 :(得分:3)

稍微加点:flyweight design pattern可用于在操作大型数据集时最大限度地减少开销。在不知道问题细节的情况下,我不确定它的适用性,但值得一看......

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

请参阅http://code.activestate.com/recipes/546530/

这是Python对象的大致大小。

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

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

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

答案 4 :(得分:1)

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

如果你正在合理地做事,那么与1000 * 8字节双数组相比,任何开销都不会很大。如果你真的担心分配开销,你可以编写自己的分配器 - 但是,首先检查它是否真的会给你一个显着的改进。

答案 5 :(得分:0)

在不知道数据的形状和您设计包含它的结构的情况下,无法回答。

答案 6 :(得分:0)

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

现在如果你有一个内存问题从多个Gb文件中读取数百万个数据,你就会遇到一个算法问题,其中对象的内存消耗肯定不是最大的问题,你需要关注的是如何获取,处理和存储数据。

答案 7 :(得分:0)

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

您可以将此数据划分为更小的子集吗?你要完成的任务是什么?我很想知道你需要内存中的所有数据。也许你可以将它序列化,或者在haskell中使用类似延迟评估的东西。

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

答案 8 :(得分:0)

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

如果我们接受C ++作为OO语言并且记住C ++编译器是C的预处理器(至少它曾经是,当我使用C ++时),用C ++完成的任何事情都是用C语言完成的.C几乎没有高架。所以它取决于库。

我认为任何开销都来自解释,管理执行或内存管理。对于那些拥有工具和技术诀窍的人来说,很容易找到最有效的,C ++或Python。

我无法看到C ++会增加多少可避​​免的开销。我对Python知之甚少。

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

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

我的意思是,谁还需要4 g的RAM呢? :)

答案 11 :(得分:0)

如果你必须定期操作数据集这么大,你能不能获得一个带有桶装RAM的64-bit machine?出于各种原因,我发现自己正在使用相当资源匮乏的软件(在本例中为SQL Server Analysis Services)。这种较旧的64位计算机可以占用大量的RAM,并且具有CPU,虽然不是最先进的,但速度仍然相当快。

我有一些二手HP工作站,并为它们安装了几个快速SCSI磁盘。在2007年中期,这些配备4或8GB RAM和5x 10K或15K SCSI磁盘的机器售价在1,500至2,000英镑之间。磁盘只是机器成本的一半,您可能不需要I / O性能,因此您可能不需要花费太多。我买的那种XW9300's现在可以很便宜地购买ebay - this posting of mine进入各种选项,使用ebay以便宜的方式获得高规格的64位盒子。这些机器可以在ebay上获得16或32GB的内存升级,只需要部分定价的一小部分。

答案 12 :(得分:0)

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

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

编辑:对不起。你说你正在重复使用物体,所以这很好。在任何情况下,当你运行它时你可以对它进行分析或(如果你是我)只需几次随机读取调用堆栈,这将回答有关时间的任何问题。

答案 13 :(得分:0)

既然您可以将数据分成两半并对其进行操作,那么我假设您正在分别处理每条记录?听起来像你需要改变你的反序列化器一次读一条记录,操纵它,然后存储结果。

基本上你需要一个字符串解析器类来执行Peek(),它返回一个char,知道如何跳过空格等。用一个类来理解你的数据格式,并且你应该可以让它吐出来一个对象,因为它读取文件。