什么是“开销”?

我是一名计算机科学专业的学生,当谈到程序和分类时,我经常听到“开销”这个词。这到底是什么意思?

开销通常是指不同编程算法所占用的额外资源(内存、处理器、时间等)的数量。

例如,插入到一个平衡二叉搜索树的开销可能比插入到一个简单的链表中的开销要大得多(插入将花费更长的时间,使用更多的处理能力来平衡树,这将导致用户更长的感知操作时间)。

132420 次浏览

例如,插入到一个平衡二叉搜索树的开销可能比插入到一个简单的链表中的开销要大得多(插入将花费更长的时间,使用更多的处理能力来平衡树,这将导致用户更长的感知操作时间)。

你可以用字典。定义是一样的。但是为了节省你的时间,日常开销是做高效工作所必需的工作。例如,一个算法运行并做有用的工作,但是需要内存来完成它的工作。这种内存分配需要时间,并且与正在完成的工作没有直接关系,因此是开销。

一个特殊的目标。这是一个特殊的 工程制造费用案例。

工程制造费用案例。

因为我们没有更好的方法,或者不值得我们花时间去“学习如何走路”。

在计算机科学中,有时候我们开车沿着街道行驶,因为我们没有更好的方法,或者不值得我们花时间去“学习如何走路”。

请注意,代码及其库等占用的磁盘空间通常不称为“开销”,而称为“内存占用”此外,您的程序所消耗的基本内存(不考虑它正在处理的任何数据集)也称为它的“内存占用”。

对于程序员来说,系统开销是指代码在给定的输入数据集上的给定平台上运行时所消耗的系统资源。这个术语通常用于比较不同的实现或可能的实现。

例如,我们可能会说,一种特定的方法可能会产生相当大的 CPU 开销,而另一种方法可能会产生更多的内存开销,而另一种方法可能会加重网络开销(例如,需要外部依赖)。

让我们举一个具体的例子: 计算一组数字的平均值(算术平均值)。

显而易见的方法是对输入进行循环,保持运行总数和计数。当遇到最后一个数字时(通过“ end of file”EOF,或者某个哨兵值,或者某个 GUI 按钮,随便什么) ,我们只需要把总数除以输入的数量就可以了。

这个词的意思因上下文的不同而有很大差异。一般来说,所使用的资源(通常是内存和 CPU 时间)并不直接影响预期的结果,而是所使用的技术或方法所需要的。例子:

    这种方法几乎不会产生 CPU、内存或其他资源方面的开销(这是一项琐碎的任务)。

    另一种可能的方法是将输入“吸入”到一个列表中。迭代列表以计算总和,然后除以列表中有效项的数目。

    相比之下,这种方法可能会产生任意数量的内存开销。

  • 协定开销 : 以太网帧、 IP 数据包和 TCP 段都有报头,TCP 连接需要握手数据包。因此,您不能使用硬件能够为您的实际数据提供的全部带宽。您可以通过使用更大的数据包大小和 UDP 有一个更小的头和没有握手来减少开销。
  • 在一个特别糟糕的实现中,我们可能使用递归执行求和操作,但是没有尾部消除。现在,除了列表中的内存开销之外,我们还引入了堆栈开销(这是一种不同类型的内存,通常比其他形式的内存资源更有限)。

    另一种(可以说更荒谬的)方法是将所有输入发布到 RDBMS 中的某个 SQL 表中。然后简单地调用该表的该列上的 SQLSUM 函数。这会将我们的本地内存开销转移到其他服务器上,并导致网络开销和对执行的外部依赖。(注意,远程服务器可能有也可能没有任何与此任务相关的特定内存开销——例如,它可能会将所有值立即存储起来)。

    假设我们可以考虑在某种集群上实现(可能是为了使数万亿值的平均值变得可行)。在这种情况下,值的任何必要的编码和分布(将它们映射到节点)以及结果的收集/整理(减少)都将被计入开销。

  • 数据结构内存开销 : 链表中包含的每个元素至少需要一个指针。如果元素的大小与指针相同,则意味着50% 的内存开销,而数组的内存开销可能为0% 。
  • 我们还可以讨论由程序员自己的代码之外的因素引起的开销。例如,编译32位或64位处理器的代码可能比编译旧的8位或16位元处理器需要更大的开销。这可能涉及较大的内存开销(对齐问题)或 CPU 开销(CPU 被迫调整位顺序或使用不对齐指令等)或两者兼而有之。

    请注意,代码及其库等占用的磁盘空间通常不称为“开销”,而称为“内存占用”此外,您的程序所消耗的基本内存(不考虑它正在处理的任何数据集)也称为它的“内存占用”。

  • 数据结构内存开销 : 链表中包含的每个元素至少需要一个指针。如果元素的大小与指针相同,则意味着50% 的内存开销,而数组的内存开销可能为0% 。
  • 方法调用开销 : 一个设计良好的程序被分解成许多短方法。但是每个方法调用都需要设置堆栈帧、复制参数和返回地址。这表示与在单个单片机函数中完成所有工作的程序相比的 CPU 开销。当然,增加的可维护性使其非常值得,但在某些情况下,过多的方法调用可能会对性能产生重大影响。
  • 开销的一个具体例子是“本地”过程调用和“远程”过程调用之间的区别。

    在计算机科学中,假设你想打印一个数字,那就是你的任务。但是存储数字、设置显示来打印它以及调用例程来打印它,然后从变量访问数字都是开销。

    假设这两个调用之间的执行时间差异很大。

    例如,对于经典的 RPC (以及许多其他远程框架,如 EJB) ,无论是本地内存调用还是分布式网络调用,对于编码器来说,函数或方法调用看起来都是相同的。

    例如:

    service.function(param1, param2);
    

    因此,虽然核心实现的“成本相同”,但涉及的“开销”是完全不同的。

    但是您可以想象,这两个调用之间的执行时间差异是巨大的。

    因此,虽然核心实现的“成本相同”,但涉及的“开销”是完全不同的。

    将开销想象成管理线程和协调它们所需的时间。如果线程没有足够的任务要完成,这是一个负担。在这种情况下,通过使用线程所节省的时间超过了开销,而且代码比顺序代码花费的时间更多。

    E 调用一个函数,在定义函数的地方传递它的控制,然后执行它的主体,这意味着我们让我们的 CPU 运行一个很长的进程(首先将控制传递到内存中的其他位置,然后在那里执行,然后将控制传递回前一位置) ,因此它需要很多性能时间,因此 Overhead。我们的目标是通过在函数定义和调用期间使用内联来减少这种开销,内联会在函数调用时复制函数的内容,因此我们不会将控件传递到其他位置,而是在一行中继续我们的程序,因此是内联的。

    为了回答你的问题,我会给你一个比喻,比如说煮饭。

    想要煮你的米饭。

    所以从商店购买大米和从水龙头取水所花费的时间是煮饭的间接费用。这些成本是我们可以避免或最小化的,相对于标准的米饭烹饪方式(一切都在你身边,你不必浪费时间收集你的原料)。

    理想情况下,当我们想做饭的时候,我们希望所有的东西都是可用的,我们希望锅子已经干净,大米有足够的数量。如果这是真的,那么我们用更少的时间煮饭(更少的开销)。

    浪费在收集材料上的时间就是我们所说的管理费用。

    另一方面,假设你现在没有干净的水,你没有大米,所以你需要先从商店里买,你还需要从你家外面的水龙头里得到干净的水。这些额外的任务不是标准的,或者让我说做饭你不一定要花那么多时间收集你的材料。理想情况下,你的原料必须在你想要煮饭的时候就已经准备好了。

    所以从商店购买大米和从水龙头取水所花费的时间是煮饭的间接费用。这些成本是我们可以避免或最小化的,相对于标准的米饭烹饪方式(一切都在你身边,你不必浪费时间收集你的原料)。

    浪费在收集材料上的时间就是我们所说的管理费用。

    在计算机科学中,例如在多线程中,线程之间的通信开销发生在线程必须轮流给予彼此对某一资源的访问权,或者它们正在相互传递信息或数据时。开销由于上下文切换而发生。尽管这对他们来说是至关重要的,但是与传统的单线程编程方式相比,这是时间(CPU 周期)的浪费,而传统的单线程编程方式在通信中从来没有时间的浪费。一个单线程程序可以立即完成这项工作。

    开销只是程序执行中消耗的更多时间。例如,当我们调用一个函数,它的控制在定义它的地方被传递,然后它的主体被执行,这意味着我们让我们的 CPU 运行通过一个长进程(首先传递控制到内存中的其他地方,然后在那里执行,然后传递控制回到前面的位置) ,因此它需要很多性能时间,因此开销。我们的目标是通过在函数定义和调用期间使用内联来减少这种开销,内联会在函数调用时复制函数的内容,因此我们不会将控件传递到其他位置,而是在一行中继续我们的程序,因此是内联的。

    另一方面,假设你现在没有干净的水,你没有大米,所以你需要先从商店里买,你还需要从你家外面的水龙头里得到干净的水。这些额外的任务不是标准的,或者让我说做饭你不一定要花那么多时间收集你的材料。理想情况下,你的原料必须在你想要煮饭的时候就已经准备好了。

    所以从商店购买大米和从水龙头取水所花费的时间是煮饭的间接费用。这些成本是我们可以避免或最小化的,相对于标准的米饭烹饪方式(一切都在你身边,你不必浪费时间收集你的原料)。

    我有这样的代码:

    for i in range(N):
    do_something()
    

    浪费在收集材料上的时间就是我们所说的管理费用。

    在计算机科学中,例如在多线程中,线程之间的通信开销发生在线程必须轮流给予彼此对某一资源的访问权,或者它们正在相互传递信息或数据时。开销由于上下文切换而发生。尽管这对他们来说是至关重要的,但是与传统的单线程编程方式相比,这是时间(CPU 周期)的浪费,而传统的单线程编程方式在通信中从来没有时间的浪费。一个单线程程序可以立即完成这项工作。