【问题标题】:Memory vs. Performance内存与性能
【发布时间】:2010-12-26 06:30:29
【问题描述】:

这一直是我编程时的想法,所以我想我会在它真正到达我之前把它吐出来。

我应该更担心什么?应用程序消耗的内存,或者它所需要的性能。我的意思是我应该专注于为应用程序使用更少的内存并使用更多的性能(例如,通过数据库加载,并在使用后转储它),还是使用更少的性能和使用更多的内存(例如缓存)

我的申请条件: - 这是一个服务器应用程序,所以它不打算在台式机等上运行,我有 6GB 的内存,我有一个四核。

【问题讨论】:

  • 内存访问也很昂贵。

标签: performance memory


【解决方案1】:

没有一个正确的选择 - 这取决于您的应用程序及其要求。然而,这通常是一种选择——你不能经常(如果有的话)最大化性能并减少内存消耗。如果这是任何类型的关键系统,则应由客户指定内存的最大界限和/或性能的最低界限 - 如果不是,则应该指定。

【讨论】:

    【解决方案2】:
    1. 让它发挥作用。

    您会得到不同的答案,而且老实说,这取决于每个应用程序。没有涵盖所有情况的一揽子答案,除了:

    1. 让它发挥作用。

    软件可能会被过度考虑。

    具体来说,大多数操作系统都非常擅长缓存磁盘 I/O —— 如果您正在使用 SQLite 数据库做大量繁重的工作,那么当您在操作系统中只有几个连接时无论如何,系统很可能会将整个事情都扔到内存中。在大多数情况下,不要想得超过操作系统。

    【讨论】:

      【解决方案3】:

      这取决于许多因素。两者中的哪一个将首先限制?其他应用程序是否需要在同一台服务器上运行?哪个更难扩展?

      【讨论】:

        【解决方案4】:

        考虑您将要处理的数据量以及您需要的响应能力。在设计中加入一些想法。将其构建为可维护的,并使其正常工作。

        然后分析并解决您的实际瓶颈。

        【讨论】:

        • 这个答案很不完整,因为它没有帮助——我认为它需要一些响应性案例的示例。为用户生成网页需要多长时间?发送电子邮件?索引 CMS 中的内容?答案是不同的,而且比“您需要的响应能力”更复杂。
        • @BobMcGee 答案与问题一样具体和完整。这个问题并没有告诉我们这是否有网页,是否涉及 CMS,是否存在电子邮件问题。这个问题需要一个一般性的答案,建议退后一步,思考什么对提问者来说应该重要。一旦他知道这一点并有一个适当的设计来解决这个问题,那么可维护性和正确性就会出现在性能之前。
        【解决方案5】:

        视情况而定

        问一个有形的问题!

        编辑:如果您在设计阶段考虑缓存,那么回到开始重新开始(缓存是 总是妥协的解决方案)!

        【讨论】:

          【解决方案6】:

          即使根据您的规范,这仍然取决于您的应用程序将要看到的工作负载。

          • 如果您一次处理少量数据,您可以通过预取接下来的 N 个块来优化性能,从而增加内存消耗。
          • 如果您的数据相当大,它可能很快就会完全填满您的主内存,并且提前读取会导致抖动(例如,提前读取会在数据完全处理之前强制将数据写回磁盘/数据库;那么您需要这些数据回到内存中,从而强制交换这些预读值)。

          所以,首先获取您的应用的工作版本。然后进行分析,看看瓶颈是什么。 (过早的优化是万恶之源!--Donald E. Knuth)

          【讨论】:

            【解决方案7】:

            它们都很重要。您可能希望在内存中缓存某些对象以获得更好的性能,这可能会增加内存占用。另一方面,如果您的应用程序花费大量时间进行垃圾收集(如在 .net 中),或者拥有尚未释放内存的非托管资源,您将遇到性能问题

            【讨论】:

              【解决方案8】:

              我认为您应该努力在内存和处理器使用之间取得平衡。

              如果您正在处理服务器组件,我会担心它会与多个用户一起使用。您的应用程序可以服务多少用户?您能否使用相同的资源吸引更多用户?

              【讨论】:

                【解决方案9】:

                您可以根据吞吐量和响应时间来考虑性能。找到测量这两个因素的方法,并设置系统需要处理和工作的负载类型。一旦您测量了负载下的吞吐量/响应时间,就会做出内存/处理时间(您称之为“性能”)的决定。通常,您应该尝试使用尽可能多的 CPU(以获得最佳吞吐量),这样您就可以利用所有可用的内存。

                【讨论】:

                  【解决方案10】:

                  这个问题与编程本身一样古老。不幸的是,答案是“视情况而定”。如果您正在为具有 32 GB RAM 的系统编写应用程序,并且您的软件是唯一可以运行的东西,那么您应该编写代码以利用它。另一方面,如果您正在编写将在嵌入式系统上运行的代码,您可能应该使用尽可能少的内存。最重要的是您了解这些权衡,分析您的代码,并优化最大的瓶颈。

                  【讨论】:

                    【解决方案11】:

                    您的问题引起了很多禅宗式的回答。我希望做得更好。

                    你的内存限制是硬的:如果你超过它,即使有虚拟内存,你的应用也会爬,你会成为所有人的笑柄。

                    您的 CPU 时间是无限的:您的应用会占用它需要的任何时间;希望它足够并行,在大多数情况下,所有 4 个 CPU 将全速烹饪,直到您的应用完成。

                    许多计算机科学问题都有多种解决方案,需要在内存与时间之间进行各种权衡。所以:要慷慨地使用内存,直到你至少使用它的一半(如果有帮助的话;不要浪费内存!)但是当有足够的内存剩余时停止,你不需要担心超过限制,即使在特殊情况下或意外情况下也是如此。

                    现在您已经分配了内存资源,您可以尝试从代码中调整一些更小的性能提升。但不要费心过度。

                    完成。

                    附:如果它不能正确可靠地工作,那么前面的所有努力都是毫无价值的。始终牢记这一点!

                    祝你好运。

                    【讨论】:

                    • CPU 时间与硬内存限制公式在理论上是正确的,但实际上您可以轻松增加内存(添加或更换 RAM 芯片),但 CPU 能力有限,增加更多贵!
                    • 我理解你的意思,你是对的(对记忆很慷慨)。但在目前的实践中,决策通常是浪费内存,尤其是在服务器应用程序中。因为内存便宜且易于扩展!
                    • 我们大多意见一致。但我想指出,在企业环境中,升级内存的实际成本可能与实际购买成本完全不相关。我曾经遇到过购买新机器比为现有机器增加内存更简单的情况[叹气]。我也同意许多开发工作会因为缺乏更好的知识而浪费资源。
                    • 我完全同意。说得好。
                    【解决方案12】:

                    这真的取决于程序的种类。如果您可以控制目标机器,它会更容易一些。如果您知道即使在极端情况下也不会耗尽内存,那么您最好使用所有您想要的东西。不被任何东西使用的内存没有任何优势。

                    总的来说,我会考虑几个类别。

                    补充程序,如果程序不执行机器的主要用途,那么它应该尝试节省内存,虽然不是服务器的东西,但我通常在这种情况下想到的例子是桌面小部件和 Tomboy .. 它们不是主要用途,因此它们不应从系统中占用太多资源,否则可能会损害主要应用程序的性能。

                    一般应用程序,这些应用程序具有简单的优先级。首先完成所需的工作,然后如果它很慢,就让它更快。除非您很鲁莽(或使用 python 或 java :-)),否则您无需过多担心内存。

                    许多实例应用程序。如果您希望用户将应用程序的许多实例作为多个任务或仅作为同一任务中的多个实例(例如多个 Firefox 窗口/选项卡),因为事情成倍增加,您需要掌握内存使用情况。速度与其说是使操作更快的问题,不如说是确保空闲实例实际上不进行任何处理。

                    Jumbo 应用程序,如果您的应用程序实际上有一个巨大的任务要执行,比如图像处理,那么您应该从一开始就考虑内存使用情况。我怀疑 Evolution 消耗了很多内存(目前在我的机器上为 142 兆),因为他们有一个巨大的任务但没有意识到这一点。我有很多电子邮件,大部分来自列表,

                    如果您可以控制您的目标环境,那么您可以根据需要拥有尽可能多的内存,这对您来说更容易。如果其他用户要使用您的程序,那么需要更多内存对您来说仍然更容易,但对用户不友好。

                    我正在开发 OLPC XO,主要是想通过补充程序使系统变得更好。这意味着我真的专注于低内存使用,但即使在内存受限的系统上,我发现进一步减少内存使用也没有多大用处。启动后,它有超过 150 兆的免费空间。这足以运行您想要的所有轻量级应用程序,但大多数较重的应用程序将是一种压力。中间立场很少。如果您正在运行像 firefox 这样的应用程序,则进一步优化 2 meg 的应用程序以仅使用 1 meg 并不会给您更多的空间。

                    【讨论】:

                    • 请注意:如今,算法和库的选择远比编程语言重要。是的,Java 和 Python 比 C 使用更多的内存,但是当您添加不同级别的 DBMS、缓存等时,算法和方法的选择就更加重要了。
                    • 我完全同意图书馆,我正在考虑写另一个讨论这个话题的回复。对于人们所说的“先让它工作,然后再分析和优化”。如果您严重依赖库,那将毫无用处。如果你先让它工作,然后分析并发现你的系统太慢/臃肿,因为你的程序建立在一个库上,通常修复问题的唯一方法是重写。如果库具有明确定义的行为界限和良好的接口,则不需要这种情况,但是太多的库想要控制您的程序结构(如 GTK 等)
                    【解决方案13】:

                    您的客户需要什么?

                    您至少应该对您的用户将在哪个平台上运行它有所了解。您还需要对性能要求(每秒事务数或其他)有所了解。对您需要的最低规格平台进行一些保守的估计,然后进行设计。

                    您在帖子中似乎也有些困惑 - 如果目的是将内存用于缓存(即您实际上是在使用节省的内存来提高性能),那么使用更少的内存并不是最终目标。在这种情况下,请选择任何能让您在每个开发人员小时内获得最大收益的方法。

                    【讨论】:

                      【解决方案14】:

                      最好不要抽象地思考,而是具体的设计。

                        1234563由于担心性能而使代码和数据结构复杂化是过早优化的本质。而且,尽管人们强烈反对过早的优化并声称他们不这样做,但他们还是会这样做,到了可怕的程度。
                      1. 当它正在工作并执行您需要它做的事情时,如果您确实有一个或多个性能问题,则处理性能问题。通常的方法是使用分析工具,但是this is the method I prefer

                      小心多核。并行性和线程允许您让多个代理在时间上重叠工作,例如磁盘磁头、CPU 或人工客户端。例如,如果您的进程受 I/O 限制,那么尝试在多个内核上执行它们不会有太大帮助,而且可能会受到伤害。如果只有一个物理磁盘驱动器,尝试重叠 I/O 绑定线程可能不会获得太多收益,而且可能会受到伤害。另一方面,如果每个用户都有一个线程,这可能是有意义的,因为这些线程大部分时间都在等待用户。

                      【讨论】:

                      • 我同意 IO 绑定。特别是考虑到较新的英特尔架构似乎要快得多,而磁盘速度并没有成比例地增加。这为使用更多内存提供了一个很好的案例——您更有可能受到磁盘的限制,并且将更多内存放入内存将保持 CPU 正常工作。
                      【解决方案15】:

                      就像其他人已经指出的那样,这取决于您的应用程序的要求。当您处理大数据时,您可能不会在程序初始加载时将所有内容都加载到 RAM 中。

                      最好从一开始就根据硬件要求设计程序。重构需要大量时间,尤其是在非常大的程序中!

                      我将列出您可以采取的不同方法以及优缺点,以便您更容易做出决定。

                      方法

                      1 - 是最好的评价
                      3 - 是最差的评级

                      1) 首先通过ORM将大对象(整个数据库)加载到RAM中

                      初始加载时间:3
                      初始加载后的性能:1
                      RAM 要求:3

                      评论:

                      初始加载后的性能:

                      • 在初始数据库查询 + ORM 之后,不再需要查询数据库。

                      备注:

                      • MVVMC 可能
                      • 不适合大数据应用。

                      2) 仅在需要时获取数据并使用 ORM

                      初始加载时间:1/2
                      初始加载后的性能:3
                      RAM 要求:2

                      评论:

                      初始加载时间:

                      • 1 或 2 取决于是否使用 MVVMC
                      • 使用 MVMC 时,必须创建 Model 和 ViewModel 对象。
                        初始加载后的性能:
                      • 数据库查询

                      内存要求:

                      • 使用 MVMC 时,必须创建 Model 和 ViewModel 对象。
                      • 由于 ORM 对获取数据的临时 RAM 要求

                      备注:

                      • MVVMC 可能

                      3) 只取需要的数据,不使用ORM,而是函数式编程

                      初始加载时间:1
                      初始加载后的性能:3
                      RAM 要求:1

                      评论:

                      初始加载后的性能:

                      • 数据库查询

                      备注:

                      • 在通过 MVVMC 使用函数式编程风格并因此直接填充视图时很有用。
                      • 更多数据库查询代码

                      【讨论】:

                        【解决方案16】:

                        现在,我在当前项目中面临同样的困境。分为三个方面:可读性速度内存。在我拥有的替代解决方案和库中,每一个在一个领域都很好。我的结论是(降序排序):

                        • 可读性(良好的语法和逻辑)
                        • 内存(将事物的内存限制为 RAM 的 1%)
                        • 速度(越快越好)

                        主要目的是编写未来证明代码。代码有一种生存、生活和繁荣的冲动。没有什么比一个好的、简单的代码更好的了:优美的语法、易于遵循的逻辑和直观的步骤。选择最易读的代码。

                        服务和应用程序按顺序共享 CPU:通过一个接一个地运行,并且通常是几微秒的空闲和等待。它们并行共享 RAM:所有共享内存。

                        实施一个解决方案,确保在实际情况下内存永远不会超过限制。记住操作系统和其他应用程序与您共享内存。几个百分比的 RAM 对于您的应用程序来说应该足够了。 然后你可以考虑解决种子瓶颈问题(太多循环或太多等待)。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2019-06-10
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2010-11-23
                          相关资源
                          最近更新 更多