代码之家  ›  专栏  ›  技术社区  ›  Alex

面向对象编程计算开销是多少?

  •  2
  • Alex  · 技术社区  · 16 年前

    我有一个大数据集(一个250000 x 1000双精度的数据立方体,大约4个gig文件),我想使用以前用python编写的一组oop类来操作它。目前,数据集已经很大,要读取到我的机器内存中,我必须至少将它分成两半,所以计算开销是一个问题。我的OOP类创建新对象(在本例中,我需要250000个新对象,每个对象都是1000个双精度数组)来处理数据。为通用OOP语言创建对象所需的内存和计算开销是多少?在蟒蛇?C++如何?

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

    *更新:我想在时间,我的时间和电脑方面高效。我不想重写我已经有的程序,如果我不需要,花时间优化代码会浪费我的时间,我不在乎 那个 如果我浪费电脑的时间,那就太多了。实际上,我有一台64位机器,带有4Gig内存。数据是一幅图像,我需要对每个像素进行多个筛选。*

    14 回复  |  直到 16 年前
        1
  •  2
  •   S.Lott    16 年前

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

    这是python对象的近似大小。

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

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

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

        2
  •  3
  •   Stephane Grenier    16 年前

    程序/函数编程语言也会有类似的问题。你如何在内存中存储那么多数据?结构或数组也不能工作。

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

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

        3
  •  3
  •   Dan Vinton    16 年前

    轻微OT: flyweight design pattern 在操作大型数据集时,可以将开销降至最低。不知道你的问题的细节,我不知道它有多适用,但它值得一看…

        4
  •  2
  •   Brian Rasmussen    16 年前

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

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

        5
  •  1
  •   comingstorm    16 年前

    实际的C++ OO内存开销是每个对象具有虚拟方法的一个指针(4-8字节,取决于它)。然而,正如其他答案中所提到的,动态分配的默认内存分配开销可能比这要大得多。

    如果你做的一半是合理的,那么与1000*8字节的双数组相比,这两种开销都不太可能有意义。如果您真的担心分配开销,您可以编写自己的分配程序——但是,首先检查一下它是否会为您带来显著的改进。

        6
  •  0
  •   Greg Hurlman    16 年前

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

        7
  •  0
  •   Loki    16 年前

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

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

        8
  •  0
  •   semmons99    16 年前

    和其他海报一样。我不认为对象会给您的进程带来很大的开销。它将需要存储一个指向对象的指针,但其余的“double”将占用程序内存的99%。

    你能把这些数据分成更小的子集吗?你想完成的任务是什么?我很想知道你需要内存中的所有数据来做什么。也许您可以将其序列化,或者在haskell中使用类似lazy评估的方法。

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

        9
  •  0
  •   Guge    16 年前

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

    如果我们接受C++作为一种面向对象语言,并且记住C++编译器是C的预处理器(至少它曾经是,当我使用C++)时,C++中所做的任何事情都是在C语言中完成的,所以开销很小。所以这将取决于图书馆。

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

    我看不出C++会增加多少可避免的开销。我对蟒蛇不太了解。

        10
  •  0
  •   Steven A. Lowe    16 年前

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

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

        11
  •  0
  •   Hace    16 年前

    请定义“操纵”。如果你真的想操作4吉格的数据,为什么你想马上把它们全部放到内存中来操作它呢?

    我是说,谁需要4吉格的内存呢?:)

        12
  •  0
  •   Mike Dunlavey    16 年前

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

    如果我是你,我会在一个扔掉的程序中尝试。我的怀疑是,除非你的类经过非常仔细的编码,否则你会发现它花费了很多时间来分配、初始化和取消分配对象,正如布莱恩所说,你可能能够通过一组重复使用的对象来缓冲数据。

    编辑:对不起。你说你用的是物体,这很好。在任何情况下,当你运行它时,你可以对它进行分析,或者(如果你是我)只是随机地读几遍调用堆栈,这将回答任何关于时间去哪里的问题。

        13
  •  0
  •   tsimon    16 年前

    既然您可以将数据分成两半并对其进行操作,那么我假设您是在分别处理每个记录?在我看来,您需要更改反序列化程序,一次读取一条记录,操作它,然后存储结果。

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

        14
  •  0
  •   Community CDub    8 年前

    如果你必须经常处理这么大的数据集,你能得到一个 64-bit machine 用桶装的闸板?出于各种原因,我发现自己正在使用相当需要资源的软件(在本例中是SQL Server Analysis Services)。这种老式64位机器可能需要大量的RAM,其CPU虽然不是最先进的,但速度仍然相当快。

    我有一些二手的HP工作站,并为它们安装了几个快速的SCSI磁盘。2007年年中,这些配备4或8GB RAM和5x 10 k或15 k SCSI磁盘的机器的购买成本介于1500英镑至2000英镑之间。磁盘是机器成本的一半,您可能不需要I/O性能,所以您可能不需要花费这么多。 XW9300's 我买的那种现在可以很便宜地在易趣上买到- this posting of mine 使用易趣以低价获得高规格64位设备的各种选择。您可以在易趣上为这些机器升级到16或32GB的内存,只需支付零件标价的一小部分。